You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ExceptionTable.java 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2006 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. package javassist.bytecode;
  16. import java.io.DataInputStream;
  17. import java.io.DataOutputStream;
  18. import java.io.IOException;
  19. import java.util.ArrayList;
  20. import java.util.Map;
  21. class ExceptionTableEntry {
  22. int startPc;
  23. int endPc;
  24. int handlerPc;
  25. int catchType;
  26. ExceptionTableEntry(int start, int end, int handle, int type) {
  27. startPc = start;
  28. endPc = end;
  29. handlerPc = handle;
  30. catchType = type;
  31. }
  32. }
  33. /**
  34. * <code>exception_table[]</code> of <code>Code_attribute</code>.
  35. */
  36. public class ExceptionTable implements Cloneable {
  37. private ConstPool constPool;
  38. private ArrayList entries;
  39. /**
  40. * Constructs an <code>exception_table[]</code>.
  41. *
  42. * @param cp constant pool table.
  43. */
  44. public ExceptionTable(ConstPool cp) {
  45. constPool = cp;
  46. entries = new ArrayList();
  47. }
  48. ExceptionTable(ConstPool cp, DataInputStream in) throws IOException {
  49. constPool = cp;
  50. int length = in.readUnsignedShort();
  51. ArrayList list = new ArrayList(length);
  52. for (int i = 0; i < length; ++i) {
  53. int start = in.readUnsignedShort();
  54. int end = in.readUnsignedShort();
  55. int handle = in.readUnsignedShort();
  56. int type = in.readUnsignedShort();
  57. list.add(new ExceptionTableEntry(start, end, handle, type));
  58. }
  59. entries = list;
  60. }
  61. /**
  62. * Creates and returns a copy of this object.
  63. * The constant pool object is shared between this object
  64. * and the cloned object.
  65. */
  66. public Object clone() throws CloneNotSupportedException {
  67. ExceptionTable r = (ExceptionTable)super.clone();
  68. r.entries = new ArrayList(entries);
  69. return r;
  70. }
  71. /**
  72. * Returns <code>exception_table_length</code>, which is the number
  73. * of entries in the <code>exception_table[]</code>.
  74. */
  75. public int size() {
  76. return entries.size();
  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. * Sets <code>startPc</code> of the <i>n</i>-th entry.
  89. *
  90. * @param nth the <i>n</i>-th (&gt;= 0).
  91. * @param value new value.
  92. */
  93. public void setStartPc(int nth, int value) {
  94. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
  95. e.startPc = value;
  96. }
  97. /**
  98. * Returns <code>endPc</code> of the <i>n</i>-th entry.
  99. *
  100. * @param nth the <i>n</i>-th (&gt;= 0).
  101. */
  102. public int endPc(int nth) {
  103. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
  104. return e.endPc;
  105. }
  106. /**
  107. * Sets <code>endPc</code> of the <i>n</i>-th entry.
  108. *
  109. * @param nth the <i>n</i>-th (&gt;= 0).
  110. * @param value new value.
  111. */
  112. public void setEndPc(int nth, int value) {
  113. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
  114. e.endPc = value;
  115. }
  116. /**
  117. * Returns <code>handlerPc</code> of the <i>n</i>-th entry.
  118. *
  119. * @param nth the <i>n</i>-th (&gt;= 0).
  120. */
  121. public int handlerPc(int nth) {
  122. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
  123. return e.handlerPc;
  124. }
  125. /**
  126. * Sets <code>handlerPc</code> of the <i>n</i>-th entry.
  127. *
  128. * @param nth the <i>n</i>-th (&gt;= 0).
  129. * @param value new value.
  130. */
  131. public void setHandlerPc(int nth, int value) {
  132. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
  133. e.handlerPc = value;
  134. }
  135. /**
  136. * Returns <code>catchType</code> of the <i>n</i>-th entry.
  137. *
  138. * @param nth the <i>n</i>-th (&gt;= 0).
  139. */
  140. public int catchType(int nth) {
  141. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
  142. return e.catchType;
  143. }
  144. /**
  145. * Sets <code>catchType</code> of the <i>n</i>-th entry.
  146. *
  147. * @param nth the <i>n</i>-th (&gt;= 0).
  148. * @param value new value.
  149. */
  150. public void setCatchType(int nth, int value) {
  151. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(nth);
  152. e.catchType = value;
  153. }
  154. /**
  155. * Copies the given exception table at the specified position
  156. * in the table.
  157. *
  158. * @param index index (&gt;= 0) at which the entry is to be inserted.
  159. * @param offset the offset added to the code position.
  160. */
  161. public void add(int index, ExceptionTable table, int offset) {
  162. int len = table.size();
  163. while (--len >= 0) {
  164. ExceptionTableEntry e
  165. = (ExceptionTableEntry)table.entries.get(len);
  166. add(index, e.startPc + offset, e.endPc + offset,
  167. e.handlerPc + offset, e.catchType);
  168. }
  169. }
  170. /**
  171. * Adds a new entry at the specified position in the table.
  172. *
  173. * @param index index (&gt;= 0) at which the entry is to be inserted.
  174. * @param start <code>startPc</code>
  175. * @param end <code>endPc</code>
  176. * @param handler <code>handlerPc</code>
  177. * @param type <code>catchType</code>
  178. */
  179. public void add(int index, int start, int end, int handler, int type) {
  180. if (start < end)
  181. entries.add(index,
  182. new ExceptionTableEntry(start, end, handler, type));
  183. }
  184. /**
  185. * Appends a new entry at the end of the table.
  186. *
  187. * @param start <code>startPc</code>
  188. * @param end <code>endPc</code>
  189. * @param handler <code>handlerPc</code>
  190. * @param type <code>catchType</code>
  191. */
  192. public void add(int start, int end, int handler, int type) {
  193. if (start < end)
  194. entries.add(new ExceptionTableEntry(start, end, handler, type));
  195. }
  196. /**
  197. * Removes the entry at the specified position in the table.
  198. *
  199. * @param index the index of the removed entry.
  200. */
  201. public void remove(int index) {
  202. entries.remove(index);
  203. }
  204. /**
  205. * Makes a copy of this <code>exception_table[]</code>.
  206. * Class names are replaced according to the
  207. * given <code>Map</code> object.
  208. *
  209. * @param newCp the constant pool table used by the new copy.
  210. * @param classnames pairs of replaced and substituted
  211. * class names.
  212. */
  213. public ExceptionTable copy(ConstPool newCp, Map classnames) {
  214. ExceptionTable et = new ExceptionTable(newCp);
  215. ConstPool srcCp = constPool;
  216. int len = size();
  217. for (int i = 0; i < len; ++i) {
  218. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
  219. int type = srcCp.copy(e.catchType, newCp, classnames);
  220. et.add(e.startPc, e.endPc, e.handlerPc, type);
  221. }
  222. return et;
  223. }
  224. void shiftPc(int where, int gapLength, boolean exclusive) {
  225. int len = size();
  226. for (int i = 0; i < len; ++i) {
  227. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
  228. e.startPc = shiftPc(e.startPc, where, gapLength, exclusive);
  229. e.endPc = shiftPc(e.endPc, where, gapLength, exclusive);
  230. e.handlerPc = shiftPc(e.handlerPc, where, gapLength, exclusive);
  231. }
  232. }
  233. private static int shiftPc(int pc, int where, int gapLength,
  234. boolean exclusive) {
  235. if (pc > where || (exclusive && pc == where))
  236. pc += gapLength;
  237. return pc;
  238. }
  239. void write(DataOutputStream out) throws IOException {
  240. int len = size();
  241. out.writeShort(len); // exception_table_length
  242. for (int i = 0; i < len; ++i) {
  243. ExceptionTableEntry e = (ExceptionTableEntry)entries.get(i);
  244. out.writeShort(e.startPc);
  245. out.writeShort(e.endPc);
  246. out.writeShort(e.handlerPc);
  247. out.writeShort(e.catchType);
  248. }
  249. }
  250. }