Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

Range.java 5.7KB

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. }