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.2KB

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