/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 (>= 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 (>= 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 (>= 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 (>= 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 (>= 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 (>= 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 (>= 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 (>= 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 (>= 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 (>= 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