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.

Range.java 5.7KB

21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
14 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.bcel;
  13. import java.util.Iterator;
  14. import org.aspectj.apache.bcel.generic.Instruction;
  15. import org.aspectj.apache.bcel.generic.InstructionConstants;
  16. import org.aspectj.apache.bcel.generic.InstructionHandle;
  17. import org.aspectj.apache.bcel.generic.InstructionList;
  18. import org.aspectj.apache.bcel.generic.InstructionTargeter;
  19. import org.aspectj.weaver.BCException;
  20. abstract class Range implements InstructionTargeter {
  21. protected InstructionList body;
  22. protected InstructionHandle start;
  23. protected InstructionHandle end;
  24. // ---- initialization
  25. protected Range(InstructionList il) {
  26. this.body = il;
  27. }
  28. // ----
  29. final InstructionList getBody() {
  30. return body;
  31. }
  32. final InstructionHandle getStart() {
  33. return start;
  34. }
  35. final InstructionHandle getEnd() {
  36. return end;
  37. }
  38. // ----
  39. boolean isEmpty() {
  40. InstructionHandle ih = start;
  41. // System.err.println(" looking for " + end);
  42. while (ih != end) {
  43. // System.err.println(" ih " + ih);
  44. if (!Range.isRangeHandle(ih)) {
  45. return false;
  46. }
  47. ih = ih.getNext();
  48. }
  49. return true;
  50. }
  51. static InstructionHandle getRealStart(InstructionHandle ih) {
  52. while (Range.isRangeHandle(ih)) {
  53. ih = ih.getNext();
  54. }
  55. return ih;
  56. }
  57. InstructionHandle getRealStart() {
  58. return getRealStart(start);
  59. }
  60. static InstructionHandle getRealEnd(InstructionHandle ih) {
  61. while (Range.isRangeHandle(ih)) {
  62. ih = ih.getPrev();
  63. }
  64. return ih;
  65. }
  66. InstructionHandle getRealEnd() {
  67. return getRealEnd(end);
  68. }
  69. InstructionHandle getRealNext() {
  70. return getRealStart(end);
  71. }
  72. // ----
  73. InstructionHandle insert(Instruction i, Where where) {
  74. InstructionList il = new InstructionList();
  75. InstructionHandle ret = il.insert(i);
  76. insert(il, where);
  77. return ret;
  78. }
  79. void insert(InstructionList freshIl, Where where) {
  80. InstructionHandle h;
  81. if (where == InsideBefore || where == OutsideBefore) {
  82. h = getStart();
  83. } else {
  84. h = getEnd();
  85. }
  86. if (where == InsideBefore || where == OutsideAfter) {
  87. body.append(h, freshIl);
  88. } else {
  89. InstructionHandle newStart = body.insert(h, freshIl);
  90. if (where == OutsideBefore) {
  91. // XXX this is slow. There's a better design than this. We should
  92. // never have to retarget branches apart from the creation of ranges.
  93. // basically, we should never weave OutsideBefore.
  94. BcelShadow.retargetAllBranches(h, newStart);
  95. }
  96. }
  97. }
  98. InstructionHandle append(Instruction i) {
  99. return insert(i, InsideAfter);
  100. }
  101. void append(InstructionList i) {
  102. insert(i, InsideAfter);
  103. }
  104. private static void setLineNumberFromNext(InstructionHandle ih) {
  105. int lineNumber = Utility.getSourceLine(ih.getNext());
  106. if (lineNumber != -1) {
  107. Utility.setSourceLine(ih, lineNumber);
  108. }
  109. }
  110. static InstructionHandle genStart(InstructionList body) {
  111. InstructionHandle ih = body.insert(Range.RANGEINSTRUCTION);
  112. setLineNumberFromNext(ih);
  113. return ih;
  114. }
  115. static InstructionHandle genEnd(InstructionList body) {
  116. return body.append(Range.RANGEINSTRUCTION);
  117. }
  118. static InstructionHandle genStart(InstructionList body, InstructionHandle ih) {
  119. if (ih == null) {
  120. return genStart(body);
  121. }
  122. InstructionHandle freshIh = body.insert(ih, Range.RANGEINSTRUCTION);
  123. setLineNumberFromNext(freshIh);
  124. return freshIh;
  125. }
  126. static InstructionHandle genEnd(InstructionList body, InstructionHandle ih) {
  127. if (ih == null) {
  128. return genEnd(body);
  129. }
  130. return body.append(ih, Range.RANGEINSTRUCTION);
  131. }
  132. // -----
  133. public boolean containsTarget(InstructionHandle ih) {
  134. return false;
  135. }
  136. public final void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
  137. throw new RuntimeException("Ranges must be updated with an enclosing instructionList");
  138. }
  139. protected void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih, InstructionList new_il) {
  140. old_ih.removeTargeter(this);
  141. if (new_ih != null) {
  142. new_ih.addTargeter(this);
  143. }
  144. body = new_il;
  145. if (old_ih == start) {
  146. start = new_ih;
  147. }
  148. if (old_ih == end) {
  149. end = new_ih;
  150. }
  151. }
  152. public static final boolean isRangeHandle(InstructionHandle ih) {
  153. if (ih == null) {
  154. return false;
  155. }
  156. return ih.getInstruction() == Range.RANGEINSTRUCTION;
  157. }
  158. protected static final Range getRange(InstructionHandle ih) {
  159. // assert isRangeHandle(ih)
  160. Range ret = null;
  161. for (InstructionTargeter targeter : ih.getTargeters()) {
  162. if (targeter instanceof Range) {
  163. Range r = (Range) targeter;
  164. if (r.getStart() != ih && r.getEnd() != ih) {
  165. continue;
  166. }
  167. if (ret != null) {
  168. throw new BCException("multiple ranges on same range handle: " + ret + ", " + targeter);
  169. }
  170. ret = r;
  171. }
  172. }
  173. if (ret == null) {
  174. throw new BCException("shouldn't happen");
  175. }
  176. return ret;
  177. }
  178. // ----
  179. static final Where InsideBefore = new Where("insideBefore");
  180. static final Where InsideAfter = new Where("insideAfter");
  181. static final Where OutsideBefore = new Where("outsideBefore");
  182. static final Where OutsideAfter = new Where("outsideAfter");
  183. // ---- constants
  184. // note that this is STUPIDLY copied by Instruction.copy(), so don't do that.
  185. public static final Instruction RANGEINSTRUCTION = InstructionConstants.IMPDEP1;
  186. // ----
  187. static class Where {
  188. private String name;
  189. public Where(String name) {
  190. this.name = name;
  191. }
  192. public String toString() {
  193. return name;
  194. }
  195. }
  196. }