Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

Range.java 5.7KB

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