Home | History | Annotate | Download | only in code
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.dx.dex.code;
     18 
     19 import com.android.dx.rop.cst.CstType;
     20 import com.android.dx.util.FixedSizeList;
     21 
     22 /**
     23  * Table of catch entries. Each entry includes a range of code
     24  * addresses for which it is valid and an associated {@link
     25  * CatchHandlerList}.
     26  */
     27 public final class CatchTable extends FixedSizeList
     28         implements Comparable<CatchTable> {
     29     /** {@code non-null;} empty instance */
     30     public static final CatchTable EMPTY = new CatchTable(0);
     31 
     32     /**
     33      * Constructs an instance. All indices initially contain {@code null}.
     34      *
     35      * @param size {@code >= 0;} the size of the table
     36      */
     37     public CatchTable(int size) {
     38         super(size);
     39     }
     40 
     41     /**
     42      * Gets the element at the given index. It is an error to call
     43      * this with the index for an element which was never set; if you
     44      * do that, this will throw {@code NullPointerException}.
     45      *
     46      * @param n {@code >= 0, < size();} which index
     47      * @return {@code non-null;} element at that index
     48      */
     49     public Entry get(int n) {
     50         return (Entry) get0(n);
     51     }
     52 
     53     /**
     54      * Sets the entry at the given index.
     55      *
     56      * @param n {@code >= 0, < size();} which index
     57      * @param entry {@code non-null;} the entry to set at {@code n}
     58      */
     59     public void set(int n, Entry entry) {
     60         set0(n, entry);
     61     }
     62 
     63     /** {@inheritDoc} */
     64     public int compareTo(CatchTable other) {
     65         if (this == other) {
     66             // Easy out.
     67             return 0;
     68         }
     69 
     70         int thisSize = size();
     71         int otherSize = other.size();
     72         int checkSize = Math.min(thisSize, otherSize);
     73 
     74         for (int i = 0; i < checkSize; i++) {
     75             Entry thisEntry = get(i);
     76             Entry otherEntry = other.get(i);
     77             int compare = thisEntry.compareTo(otherEntry);
     78             if (compare != 0) {
     79                 return compare;
     80             }
     81         }
     82 
     83         if (thisSize < otherSize) {
     84             return -1;
     85         } else if (thisSize > otherSize) {
     86             return 1;
     87         }
     88 
     89         return 0;
     90     }
     91 
     92     /**
     93      * Entry in a catch list.
     94      */
     95     public static class Entry implements Comparable<Entry> {
     96         /** {@code >= 0;} start address */
     97         private final int start;
     98 
     99         /** {@code > start;} end address (exclusive) */
    100         private final int end;
    101 
    102         /** {@code non-null;} list of catch handlers */
    103         private final CatchHandlerList handlers;
    104 
    105         /**
    106          * Constructs an instance.
    107          *
    108          * @param start {@code >= 0;} start address
    109          * @param end {@code > start;} end address (exclusive)
    110          * @param handlers {@code non-null;} list of catch handlers
    111          */
    112         public Entry(int start, int end, CatchHandlerList handlers) {
    113             if (start < 0) {
    114                 throw new IllegalArgumentException("start < 0");
    115             }
    116 
    117             if (end <= start) {
    118                 throw new IllegalArgumentException("end <= start");
    119             }
    120 
    121             if (handlers.isMutable()) {
    122                 throw new IllegalArgumentException("handlers.isMutable()");
    123             }
    124 
    125             this.start = start;
    126             this.end = end;
    127             this.handlers = handlers;
    128         }
    129 
    130         /** {@inheritDoc} */
    131         @Override
    132         public int hashCode() {
    133             int hash = (start * 31) + end;
    134             hash = (hash * 31) + handlers.hashCode();
    135             return hash;
    136         }
    137 
    138         /** {@inheritDoc} */
    139         @Override
    140         public boolean equals(Object other) {
    141             if (other instanceof Entry) {
    142                 return (compareTo((Entry) other) == 0);
    143             }
    144 
    145             return false;
    146         }
    147 
    148         /** {@inheritDoc} */
    149         public int compareTo(Entry other) {
    150             if (start < other.start) {
    151                 return -1;
    152             } else if (start > other.start) {
    153                 return 1;
    154             }
    155 
    156             if (end < other.end) {
    157                 return -1;
    158             } else if (end > other.end) {
    159                 return 1;
    160             }
    161 
    162             return handlers.compareTo(other.handlers);
    163         }
    164 
    165         /**
    166          * Gets the start address.
    167          *
    168          * @return {@code >= 0;} the start address
    169          */
    170         public int getStart() {
    171             return start;
    172         }
    173 
    174         /**
    175          * Gets the end address (exclusive).
    176          *
    177          * @return {@code > start;} the end address (exclusive)
    178          */
    179         public int getEnd() {
    180             return end;
    181         }
    182 
    183         /**
    184          * Gets the handlers.
    185          *
    186          * @return {@code non-null;} the handlers
    187          */
    188         public CatchHandlerList getHandlers() {
    189             return handlers;
    190         }
    191     }
    192 }
    193