Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

LineNumberAttribute.java 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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.IOException;
  19. import java.util.Map;
  20. /**
  21. * <code>LineNumberTable_attribute</code>.
  22. */
  23. public class LineNumberAttribute extends AttributeInfo {
  24. /**
  25. * The name of this attribute <code>"LineNumberTable"</code>.
  26. */
  27. public static final String tag = "LineNumberTable";
  28. LineNumberAttribute(ConstPool cp, int n, DataInputStream in)
  29. throws IOException
  30. {
  31. super(cp, n, in);
  32. }
  33. private LineNumberAttribute(ConstPool cp, byte[] i) {
  34. super(cp, tag, i);
  35. }
  36. /**
  37. * Returns <code>line_number_table_length</code>.
  38. * This represents the number of entries in the table.
  39. */
  40. public int tableLength() {
  41. return ByteArray.readU16bit(info, 0);
  42. }
  43. /**
  44. * Returns <code>line_number_table[i].start_pc</code>.
  45. * This represents the index into the code array at which the code
  46. * for a new line in the original source file begins.
  47. *
  48. * @param i the i-th entry.
  49. */
  50. public int startPc(int i) {
  51. return ByteArray.readU16bit(info, i * 4 + 2);
  52. }
  53. /**
  54. * Returns <code>line_number_table[i].line_number</code>.
  55. * This represents the corresponding line number in the original
  56. * source file.
  57. *
  58. * @param i the i-th entry.
  59. */
  60. public int lineNumber(int i) {
  61. return ByteArray.readU16bit(info, i * 4 + 4);
  62. }
  63. /**
  64. * Returns the line number corresponding to the specified bytecode.
  65. *
  66. * @param pc the index into the code array.
  67. */
  68. public int toLineNumber(int pc) {
  69. int n = tableLength();
  70. int i = 0;
  71. for (; i < n; ++i)
  72. if (pc < startPc(i))
  73. if (i == 0)
  74. return lineNumber(0);
  75. else
  76. break;
  77. return lineNumber(i - 1);
  78. }
  79. /**
  80. * Returns the index into the code array at which the code for
  81. * the specified line begins.
  82. *
  83. * @param line the line number.
  84. * @return -1 if the specified line is not found.
  85. */
  86. public int toStartPc(int line) {
  87. int n = tableLength();
  88. for (int i = 0; i < n; ++i)
  89. if (line == lineNumber(i))
  90. return startPc(i);
  91. return -1;
  92. }
  93. /**
  94. * Used as a return type of <code>toNearPc()</code>.
  95. */
  96. static public class Pc {
  97. /**
  98. * The index into the code array.
  99. */
  100. public int index;
  101. /**
  102. * The line number.
  103. */
  104. public int line;
  105. }
  106. /**
  107. * Returns the index into the code array at which the code for
  108. * the specified line (or the nearest line after the specified one)
  109. * begins.
  110. *
  111. * @param line the line number.
  112. * @return a pair of the index and the line number of the
  113. * bytecode at that index.
  114. */
  115. public Pc toNearPc(int line) {
  116. int n = tableLength();
  117. int nearPc = 0;
  118. int distance = 0;
  119. if (n > 0) {
  120. distance = lineNumber(0) - line;
  121. nearPc = startPc(0);
  122. }
  123. for (int i = 1; i < n; ++i) {
  124. int d = lineNumber(i) - line;
  125. if ((d < 0 && d > distance)
  126. || (d >= 0 && (d < distance || distance < 0))) {
  127. distance = d;
  128. nearPc = startPc(i);
  129. }
  130. }
  131. Pc res = new Pc();
  132. res.index = nearPc;
  133. res.line = line + distance;
  134. return res;
  135. }
  136. /**
  137. * Makes a copy.
  138. *
  139. * @param newCp the constant pool table used by the new copy.
  140. * @param classnames should be null.
  141. */
  142. @Override
  143. public AttributeInfo copy(ConstPool newCp, Map<String,String> classnames) {
  144. byte[] src = info;
  145. int num = src.length;
  146. byte[] dest = new byte[num];
  147. for (int i = 0; i < num; ++i)
  148. dest[i] = src[i];
  149. LineNumberAttribute attr = new LineNumberAttribute(newCp, dest);
  150. return attr;
  151. }
  152. /**
  153. * Adjusts start_pc if bytecode is inserted in a method body.
  154. */
  155. void shiftPc(int where, int gapLength, boolean exclusive) {
  156. int n = tableLength();
  157. for (int i = 0; i < n; ++i) {
  158. int pos = i * 4 + 2;
  159. int pc = ByteArray.readU16bit(info, pos);
  160. if (pc > where || (exclusive && pc == where))
  161. ByteArray.write16bit(pc + gapLength, info, pos);
  162. }
  163. }
  164. }