/Users/lyon/j4p/src/javassist/bytecode/ExceptionTable.java

1    /* 
2     * Javassist, a Java-bytecode translator toolkit. 
3     * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved. 
4     * 
5     * The contents of this file are subject to the Mozilla Public License Version 
6     * 1.1 (the "License"); you may not use this file except in compliance with 
7     * the License.  Alternatively, the contents of this file may be used under 
8     * the terms of the GNU Lesser General Public License Version 2.1 or later. 
9     * 
10    * Software distributed under the License is distributed on an "AS IS" basis, 
11    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
12    * for the specific language governing rights and limitations under the 
13    * License. 
14    */ 
15    
16   package javassist.bytecode; 
17    
18   import java.io.DataInputStream; 
19   import java.io.DataOutputStream; 
20   import java.io.IOException; 
21   import java.util.ArrayList; 
22   import java.util.Map; 
23    
24   class ExceptionTableEntry { 
25       int startPc; 
26       int endPc; 
27       int handlerPc; 
28       int catchType; 
29    
30       ExceptionTableEntry(int start, int end, int handle, int type) { 
31           startPc = start; 
32           endPc = end; 
33           handlerPc = handle; 
34           catchType = type; 
35       } 
36   } 
37    
38   /** 
39    * <code>exception_table[]</code> of <code>Code_attribute</code>. 
40    */ 
41   public class ExceptionTable { 
42       private ConstPool constPool; 
43       private ArrayList entries; 
44    
45       /** 
46        * Constructs an <code>exception_table[]</code>. 
47        * 
48        * @param cp        constant pool table. 
49        */ 
50       public ExceptionTable(ConstPool cp) { 
51           constPool = cp; 
52           entries = new ArrayList(); 
53       } 
54    
55       ExceptionTable(ConstPool cp, DataInputStream in) throws IOException { 
56           constPool = cp; 
57           int length = in.readUnsignedShort(); 
58           ArrayList list = new ArrayList(length); 
59           for (int i = 0; i < length; ++i) { 
60               int start = in.readUnsignedShort(); 
61               int end = in.readUnsignedShort(); 
62               int handle = in.readUnsignedShort(); 
63               int type = in.readUnsignedShort(); 
64               list.add(new ExceptionTableEntry(start, end, handle, type)); 
65           } 
66    
67           entries = list; 
68       } 
69    
70       /** 
71        * Returns <code>exception_table_length</code>, which is the number 
72        * of entries in the <code>exception_table[]</code>. 
73        */ 
74       public int size() { 
75           return entries.size(); 
76       } 
77    
78       /** 
79        * Returns <code>startPc</code> of the <i>n</i>-th entry. 
80        * 
81        * @param nth               the <i>n</i>-th (&gt;= 0). 
82        */ 
83       public int startPc(int nth) { 
84           ExceptionTableEntry e = (ExceptionTableEntry) entries.get(nth); 
85           return e.startPc; 
86       } 
87    
88       /** 
89        * Sets <code>startPc</code> of the <i>n</i>-th entry. 
90        * 
91        * @param nth               the <i>n</i>-th (&gt;= 0). 
92        * @param value             new value. 
93        */ 
94       public void setStartPc(int nth, int value) { 
95           ExceptionTableEntry e = (ExceptionTableEntry) entries.get(nth); 
96           e.startPc = value; 
97       } 
98    
99       /** 
100       * Returns <code>endPc</code> of the <i>n</i>-th entry. 
101       * 
102       * @param nth               the <i>n</i>-th (&gt;= 0). 
103       */ 
104      public int endPc(int nth) { 
105          ExceptionTableEntry e = (ExceptionTableEntry) entries.get(nth); 
106          return e.endPc; 
107      } 
108   
109      /** 
110       * Sets <code>endPc</code> of the <i>n</i>-th entry. 
111       * 
112       * @param nth               the <i>n</i>-th (&gt;= 0). 
113       * @param value             new value. 
114       */ 
115      public void setEndPc(int nth, int value) { 
116          ExceptionTableEntry e = (ExceptionTableEntry) entries.get(nth); 
117          e.endPc = value; 
118      } 
119   
120      /** 
121       * Returns <code>handlerPc</code> of the <i>n</i>-th entry. 
122       * 
123       * @param nth               the <i>n</i>-th (&gt;= 0). 
124       */ 
125      public int handlerPc(int nth) { 
126          ExceptionTableEntry e = (ExceptionTableEntry) entries.get(nth); 
127          return e.handlerPc; 
128      } 
129   
130      /** 
131       * Sets <code>handlerPc</code> of the <i>n</i>-th entry. 
132       * 
133       * @param nth               the <i>n</i>-th (&gt;= 0). 
134       * @param value             new value. 
135       */ 
136      public void setHandlerPc(int nth, int value) { 
137          ExceptionTableEntry e = (ExceptionTableEntry) entries.get(nth); 
138          e.handlerPc = value; 
139      } 
140   
141      /** 
142       * Returns <code>catchType</code> of the <i>n</i>-th entry. 
143       * 
144       * @param nth               the <i>n</i>-th (&gt;= 0). 
145       */ 
146      public int catchType(int nth) { 
147          ExceptionTableEntry e = (ExceptionTableEntry) entries.get(nth); 
148          return e.catchType; 
149      } 
150   
151      /** 
152       * Sets <code>catchType</code> of the <i>n</i>-th entry. 
153       * 
154       * @param nth               the <i>n</i>-th (&gt;= 0). 
155       * @param value             new value. 
156       */ 
157      public void setCatchType(int nth, int value) { 
158          ExceptionTableEntry e = (ExceptionTableEntry) entries.get(nth); 
159          e.catchType = value; 
160      } 
161   
162      /** 
163       * Copies the given exception table at the specified position 
164       * in the table. 
165       * 
166       * @param index     index (&gt;= 0) at which the entry is to be inserted. 
167       * @param offset    the offset added to the code position. 
168       */ 
169      public void add(int index, ExceptionTable table, int offset) { 
170          int len = table.size(); 
171          while (--len >= 0) { 
172              ExceptionTableEntry e 
173                      = (ExceptionTableEntry) table.entries.get(len); 
174              add(index, e.startPc + offset, e.endPc + offset, 
175                      e.handlerPc + offset, e.catchType); 
176          } 
177      } 
178   
179      /** 
180       * Adds a new entry at the specified position in the table. 
181       * 
182       * @param index     index (&gt;= 0) at which the entry is to be inserted. 
183       * @param start     <code>startPc</code> 
184       * @param end       <code>endPc</code> 
185       * @param handler   <code>handlerPc</code> 
186       * @param type      <code>catchType</code> 
187       */ 
188      public void add(int index, int start, int end, int handler, int type) { 
189          entries.add(index, 
190                  new ExceptionTableEntry(start, end, handler, type)); 
191      } 
192   
193      /** 
194       * Appends a new entry at the end of the table. 
195       * 
196       * @param start     <code>startPc</code> 
197       * @param end       <code>endPc</code> 
198       * @param handler   <code>handlerPc</code> 
199       * @param type      <code>catchType</code> 
200       */ 
201      public void add(int start, int end, int handler, int type) { 
202          entries.add(new ExceptionTableEntry(start, end, handler, type)); 
203      } 
204   
205      /** 
206       * Removes the entry at the specified position in the table. 
207       * 
208       * @param index     the index of the removed entry. 
209       */ 
210      public void remove(int index) { 
211          entries.remove(index); 
212      } 
213   
214      /** 
215       * Makes a copy of this <code>exception_table[]</code>. 
216       * Class names are replaced according to the 
217       * given <code>Map</code> object. 
218       * 
219       * @param newCp     the constant pool table used by the new copy. 
220       * @param classnames        pairs of replaced and substituted 
221       *                          class names. 
222       */ 
223      public ExceptionTable copy(ConstPool newCp, Map classnames) { 
224          ExceptionTable et = new ExceptionTable(newCp); 
225          ConstPool srcCp = constPool; 
226          int len = size(); 
227          for (int i = 0; i < len; ++i) { 
228              ExceptionTableEntry e = (ExceptionTableEntry) entries.get(i); 
229              int type = srcCp.copy(e.catchType, newCp, classnames); 
230              et.add(e.startPc, e.endPc, e.handlerPc, type); 
231          } 
232   
233          return et; 
234      } 
235   
236      void shiftPc(int where, int gapLength, boolean exclusive) { 
237          int len = size(); 
238          for (int i = 0; i < len; ++i) { 
239              ExceptionTableEntry e = (ExceptionTableEntry) entries.get(i); 
240              e.startPc = shiftPc(e.startPc, where, gapLength, exclusive); 
241              e.endPc = shiftPc(e.endPc, where, gapLength, exclusive); 
242              e.handlerPc = shiftPc(e.handlerPc, where, gapLength, exclusive); 
243          } 
244      } 
245   
246      private static int shiftPc(int pc, int where, int gapLength, 
247                                 boolean exclusive) { 
248          if (pc > where || (exclusive && pc == where)) 
249              pc += gapLength; 
250   
251          return pc; 
252      } 
253   
254      void write(DataOutputStream out) throws IOException { 
255          int len = size(); 
256          out.writeShort(len);            // exception_table_length 
257          for (int i = 0; i < len; ++i) { 
258              ExceptionTableEntry e = (ExceptionTableEntry) entries.get(i); 
259              out.writeShort(e.startPc); 
260              out.writeShort(e.endPc); 
261              out.writeShort(e.handlerPc); 
262              out.writeShort(e.catchType); 
263          } 
264      } 
265  } 
266