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.

BcelTypeMunger.java 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  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 Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.bcel;
  13. import java.lang.reflect.Modifier;
  14. import java.util.Iterator;
  15. import java.util.Set;
  16. import org.apache.bcel.Constants;
  17. import org.apache.bcel.generic.FieldGen;
  18. import org.apache.bcel.generic.InstructionFactory;
  19. import org.apache.bcel.generic.InstructionList;
  20. import org.apache.bcel.generic.Type;
  21. import org.aspectj.weaver.AjcMemberMaker;
  22. import org.aspectj.weaver.ConcreteTypeMunger;
  23. import org.aspectj.weaver.Member;
  24. import org.aspectj.weaver.NameMangler;
  25. import org.aspectj.weaver.NewConstructorTypeMunger;
  26. import org.aspectj.weaver.NewFieldTypeMunger;
  27. import org.aspectj.weaver.NewMethodTypeMunger;
  28. import org.aspectj.weaver.NewParentTypeMunger;
  29. import org.aspectj.weaver.PerObjectInterfaceTypeMunger;
  30. import org.aspectj.weaver.PrivilegedAccessMunger;
  31. import org.aspectj.weaver.ResolvedMember;
  32. import org.aspectj.weaver.ResolvedTypeMunger;
  33. import org.aspectj.weaver.ResolvedTypeX;
  34. import org.aspectj.weaver.TypeX;
  35. import org.aspectj.weaver.WeaverStateInfo;
  36. import org.aspectj.weaver.patterns.Pointcut;
  37. //XXX addLazyMethodGen is probably bad everywhere
  38. public class BcelTypeMunger extends ConcreteTypeMunger {
  39. public BcelTypeMunger(ResolvedTypeMunger munger, ResolvedTypeX aspectType) {
  40. super(munger, aspectType);
  41. }
  42. public String toString() {
  43. return "(BcelTypeMunger " + getMunger() + ")";
  44. }
  45. public boolean munge(BcelClassWeaver weaver) {
  46. boolean changed = false;
  47. if (munger.getKind() == ResolvedTypeMunger.Field) {
  48. changed = mungeNewField(weaver, (NewFieldTypeMunger)munger);
  49. } else if (munger.getKind() == ResolvedTypeMunger.Method) {
  50. changed = mungeNewMethod(weaver, (NewMethodTypeMunger)munger);
  51. } else if (munger.getKind() == ResolvedTypeMunger.PerObjectInterface) {
  52. changed = mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger)munger);
  53. } else if (munger.getKind() == ResolvedTypeMunger.PrivilegedAccess) {
  54. changed = mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger);
  55. } else if (munger.getKind() == ResolvedTypeMunger.Constructor) {
  56. changed = mungeNewConstructor(weaver, (NewConstructorTypeMunger)munger);
  57. } else if (munger.getKind() == ResolvedTypeMunger.Parent) {
  58. changed = mungeNewParent(weaver, (NewParentTypeMunger)munger);
  59. } else {
  60. throw new RuntimeException("unimplemented");
  61. }
  62. if (changed && munger.changesPublicSignature()) {
  63. WeaverStateInfo info =
  64. weaver.getLazyClassGen().getOrCreateWeaverStateInfo();
  65. info.addConcreteMunger(this);
  66. }
  67. return changed;
  68. }
  69. private boolean mungeNewParent(BcelClassWeaver weaver, NewParentTypeMunger munger) {
  70. LazyClassGen gen = weaver.getLazyClassGen();
  71. ResolvedTypeX newParent = munger.getNewParent();
  72. if (newParent.isClass()) {
  73. //gen.setSuperClass(newParent);
  74. } else {
  75. gen.addInterface(newParent);
  76. }
  77. return true;
  78. }
  79. private boolean mungePrivilegedAccess(
  80. BcelClassWeaver weaver,
  81. PrivilegedAccessMunger munger)
  82. {
  83. LazyClassGen gen = weaver.getLazyClassGen();
  84. ResolvedMember member = munger.getMember();
  85. ResolvedTypeX onType = weaver.getWorld().resolve(member.getDeclaringType());
  86. //System.out.println("munging: " + gen + " with " + member);
  87. if (onType.equals(gen.getType())) {
  88. if (member.getKind() == Member.FIELD) {
  89. //System.out.println("matched: " + gen);
  90. addFieldGetter(gen, member,
  91. AjcMemberMaker.privilegedAccessMethodForFieldGet(aspectType, member));
  92. addFieldSetter(gen, member,
  93. AjcMemberMaker.privilegedAccessMethodForFieldSet(aspectType, member));
  94. return true;
  95. } else if (member.getKind() == Member.METHOD) {
  96. addMethodDispatch(gen, member,
  97. AjcMemberMaker.privilegedAccessMethodForMethod(aspectType, member));
  98. return true;
  99. } else if (member.getKind() == Member.CONSTRUCTOR) {
  100. for (Iterator i = gen.getMethodGens().iterator(); i.hasNext(); ) {
  101. LazyMethodGen m = (LazyMethodGen)i.next();
  102. if (m.getMemberView() != null && m.getMemberView().getKind() == Member.CONSTRUCTOR) {
  103. // m.getMemberView().equals(member)) {
  104. m.forcePublic();
  105. //return true;
  106. }
  107. }
  108. return true;
  109. //throw new BCException("no match for " + member + " in " + gen);
  110. } else if (member.getKind() == Member.STATIC_INITIALIZATION) {
  111. gen.forcePublic();
  112. return true;
  113. } else {
  114. throw new RuntimeException("unimplemented");
  115. }
  116. }
  117. return false;
  118. }
  119. private void addFieldGetter(
  120. LazyClassGen gen,
  121. ResolvedMember field,
  122. ResolvedMember accessMethod)
  123. {
  124. LazyMethodGen mg = makeMethodGen(gen, accessMethod);
  125. InstructionList il = new InstructionList();
  126. InstructionFactory fact = gen.getFactory();
  127. if (field.isStatic()) {
  128. il.append(fact.createFieldAccess(
  129. gen.getClassName(),
  130. field.getName(),
  131. BcelWorld.makeBcelType(field.getType()), Constants.GETSTATIC));
  132. } else {
  133. il.append(fact.ALOAD_0);
  134. il.append(fact.createFieldAccess(
  135. gen.getClassName(),
  136. field.getName(),
  137. BcelWorld.makeBcelType(field.getType()), Constants.GETFIELD));
  138. }
  139. il.append(fact.createReturn(BcelWorld.makeBcelType(field.getType())));
  140. mg.getBody().insert(il);
  141. gen.addMethodGen(mg);
  142. }
  143. private void addFieldSetter(
  144. LazyClassGen gen,
  145. ResolvedMember field,
  146. ResolvedMember accessMethod)
  147. {
  148. LazyMethodGen mg = makeMethodGen(gen, accessMethod);
  149. InstructionList il = new InstructionList();
  150. InstructionFactory fact = gen.getFactory();
  151. Type fieldType = BcelWorld.makeBcelType(field.getType());
  152. if (field.isStatic()) {
  153. il.append(fact.createLoad(fieldType, 0));
  154. il.append(fact.createFieldAccess(
  155. gen.getClassName(),
  156. field.getName(),
  157. fieldType, Constants.PUTSTATIC));
  158. } else {
  159. il.append(fact.ALOAD_0);
  160. il.append(fact.createLoad(fieldType, 1));
  161. il.append(fact.createFieldAccess(
  162. gen.getClassName(),
  163. field.getName(),
  164. fieldType, Constants.PUTFIELD));
  165. }
  166. il.append(fact.createReturn(Type.VOID));
  167. mg.getBody().insert(il);
  168. gen.addMethodGen(mg);
  169. }
  170. private void addMethodDispatch(
  171. LazyClassGen gen,
  172. ResolvedMember method,
  173. ResolvedMember accessMethod)
  174. {
  175. LazyMethodGen mg = makeMethodGen(gen, accessMethod);
  176. InstructionList il = new InstructionList();
  177. InstructionFactory fact = gen.getFactory();
  178. //Type fieldType = BcelWorld.makeBcelType(field.getType());
  179. Type[] paramTypes = BcelWorld.makeBcelTypes(method.getParameterTypes());
  180. int pos = 0;
  181. if (!method.isStatic()) {
  182. il.append(fact.ALOAD_0);
  183. pos++;
  184. }
  185. for (int i = 0, len = paramTypes.length; i < len; i++) {
  186. Type paramType = paramTypes[i];
  187. il.append(fact.createLoad(paramType, pos));
  188. pos+=paramType.getSize();
  189. }
  190. il.append(Utility.createInvoke(fact, (BcelWorld)aspectType.getWorld(),
  191. method));
  192. il.append(fact.createReturn(BcelWorld.makeBcelType(method.getReturnType())));
  193. mg.getBody().insert(il);
  194. gen.addMethodGen(mg);
  195. }
  196. private LazyMethodGen makeMethodGen(LazyClassGen gen, ResolvedMember member) {
  197. LazyMethodGen ret = new LazyMethodGen(
  198. member.getModifiers(),
  199. BcelWorld.makeBcelType(member.getReturnType()),
  200. member.getName(),
  201. BcelWorld.makeBcelTypes(member.getParameterTypes()),
  202. TypeX.getNames(member.getExceptions()),
  203. gen);
  204. ret.makeSynthetic();
  205. return ret;
  206. }
  207. private FieldGen makeFieldGen(LazyClassGen gen, ResolvedMember member) {
  208. return new FieldGen(
  209. member.getModifiers(),
  210. BcelWorld.makeBcelType(member.getReturnType()),
  211. member.getName(),
  212. gen.getConstantPoolGen());
  213. }
  214. private boolean mungePerObjectInterface(
  215. BcelClassWeaver weaver,
  216. PerObjectInterfaceTypeMunger munger)
  217. {
  218. LazyClassGen gen = weaver.getLazyClassGen();
  219. if (couldMatch(gen.getBcelObjectType(), munger.getTestPointcut())) {
  220. FieldGen fg = makeFieldGen(gen,
  221. AjcMemberMaker.perObjectField(gen.getType(), aspectType));
  222. gen.addField(fg.getField());
  223. Type fieldType = BcelWorld.makeBcelType(aspectType);
  224. LazyMethodGen mg = new LazyMethodGen(
  225. Modifier.PUBLIC,
  226. fieldType,
  227. NameMangler.perObjectInterfaceGet(aspectType),
  228. new Type[0], new String[0],
  229. gen);
  230. InstructionList il = new InstructionList();
  231. InstructionFactory fact = gen.getFactory();
  232. il.append(fact.ALOAD_0);
  233. il.append(fact.createFieldAccess(
  234. gen.getClassName(),
  235. fg.getName(),
  236. fieldType, Constants.GETFIELD));
  237. il.append(fact.createReturn(fieldType));
  238. mg.getBody().insert(il);
  239. gen.addMethodGen(mg);
  240. LazyMethodGen mg1 = new LazyMethodGen(
  241. Modifier.PUBLIC,
  242. Type.VOID,
  243. NameMangler.perObjectInterfaceSet(aspectType),
  244. new Type[]{fieldType,}, new String[0],
  245. gen);
  246. InstructionList il1 = new InstructionList();
  247. il1.append(fact.ALOAD_0);
  248. il1.append(fact.createLoad(fieldType, 1));
  249. il1.append(fact.createFieldAccess(
  250. gen.getClassName(),
  251. fg.getName(),
  252. fieldType, Constants.PUTFIELD));
  253. il1.append(fact.createReturn(Type.VOID));
  254. mg1.getBody().insert(il1);
  255. gen.addMethodGen(mg1);
  256. gen.addInterface(munger.getInterfaceType());
  257. return true;
  258. } else {
  259. return false;
  260. }
  261. }
  262. private boolean couldMatch(
  263. BcelObjectType bcelObjectType,
  264. Pointcut pointcut) {
  265. return !bcelObjectType.isInterface();
  266. }
  267. private boolean mungeNewMethod(BcelClassWeaver weaver, NewMethodTypeMunger munger) {
  268. ResolvedMember signature = munger.getSignature();
  269. ResolvedMember dispatchMethod = munger.getDispatchMethod(aspectType);
  270. LazyClassGen gen = weaver.getLazyClassGen();
  271. ResolvedTypeX onType = weaver.getWorld().resolve(signature.getDeclaringType());
  272. boolean onInterface = onType.isInterface();
  273. if (onType.equals(gen.getType())) {
  274. ResolvedMember introMethod =
  275. AjcMemberMaker.interMethod(signature, aspectType, onInterface);
  276. LazyMethodGen mg = makeMethodGen(gen, introMethod);
  277. if (!onInterface && !Modifier.isAbstract(introMethod.getModifiers())) {
  278. InstructionList body = mg.getBody();
  279. InstructionFactory fact = gen.getFactory();
  280. int pos = 0;
  281. if (!signature.isStatic()) {
  282. body.append(fact.createThis());
  283. pos++;
  284. }
  285. Type[] paramTypes = BcelWorld.makeBcelTypes(introMethod.getParameterTypes());
  286. for (int i = 0, len = paramTypes.length; i < len; i++) {
  287. Type paramType = paramTypes[i];
  288. body.append(fact.createLoad(paramType, pos));
  289. pos+=paramType.getSize();
  290. }
  291. body.append(Utility.createInvoke(fact, weaver.getWorld(), dispatchMethod));
  292. body.append(fact.createReturn(BcelWorld.makeBcelType(introMethod.getReturnType())));
  293. } else {
  294. //??? this is okay
  295. //if (!(mg.getBody() == null)) throw new RuntimeException("bas");
  296. }
  297. // XXX make sure to check that we set exceptions properly on this guy.
  298. weaver.addLazyMethodGen(mg);
  299. addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
  300. return true;
  301. } else if (onInterface && gen.getType().isTopmostImplementor(onType) &&
  302. !Modifier.isAbstract(signature.getModifiers()))
  303. {
  304. ResolvedMember introMethod =
  305. AjcMemberMaker.interMethod(signature, aspectType, false);
  306. LazyMethodGen mg = makeMethodGen(gen, introMethod);
  307. //
  308. Type[] paramTypes = BcelWorld.makeBcelTypes(introMethod.getParameterTypes());
  309. Type returnType = BcelWorld.makeBcelType(introMethod.getReturnType());
  310. InstructionList body = mg.getBody();
  311. InstructionFactory fact = gen.getFactory();
  312. int pos = 0;
  313. if (!introMethod.isStatic()) {
  314. body.append(fact.createThis());
  315. pos++;
  316. }
  317. for (int i = 0, len = paramTypes.length; i < len; i++) {
  318. Type paramType = paramTypes[i];
  319. body.append(fact.createLoad(paramType, pos));
  320. pos+=paramType.getSize();
  321. }
  322. body.append(Utility.createInvoke(fact, weaver.getWorld(), dispatchMethod));
  323. body.append(fact.createReturn(returnType));
  324. mg.definingType = onType;
  325. weaver.addOrReplaceLazyMethodGen(mg);
  326. addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
  327. return true;
  328. } else {
  329. return false;
  330. }
  331. }
  332. private void addNeededSuperCallMethods(
  333. BcelClassWeaver weaver,
  334. ResolvedTypeX onType,
  335. Set neededSuperCalls)
  336. {
  337. LazyClassGen gen = weaver.getLazyClassGen();
  338. for (Iterator iter = neededSuperCalls.iterator(); iter.hasNext(); ) {
  339. ResolvedMember superMethod = (ResolvedMember) iter.next();
  340. if (weaver.addDispatchTarget(superMethod)) {
  341. //System.err.println("super type: " + superMethod.getDeclaringType() + ", " + gen.getType());
  342. boolean isSuper = !superMethod.getDeclaringType().equals(gen.getType());
  343. String dispatchName;
  344. if (isSuper) dispatchName = NameMangler.superDispatchMethod(onType, superMethod.getName());
  345. else dispatchName = NameMangler.protectedDispatchMethod(onType, superMethod.getName());
  346. LazyMethodGen dispatcher = makeDispatcher(gen, dispatchName, superMethod, weaver.getWorld(), isSuper);
  347. weaver.addLazyMethodGen(dispatcher);
  348. }
  349. }
  350. }
  351. private boolean mungeNewConstructor(
  352. BcelClassWeaver weaver,
  353. NewConstructorTypeMunger newConstructorTypeMunger)
  354. {
  355. final LazyClassGen currentClass = weaver.getLazyClassGen();
  356. final InstructionFactory fact = currentClass.getFactory();
  357. ResolvedMember newConstructorMember = newConstructorTypeMunger.getSyntheticConstructor();
  358. TypeX onType = newConstructorMember.getDeclaringType();
  359. if (! onType.equals(currentClass.getType())) return false;
  360. ResolvedMember explicitConstructor = newConstructorTypeMunger.getExplicitConstructor();
  361. //int declaredParameterCount = newConstructorTypeMunger.getDeclaredParameterCount();
  362. LazyMethodGen freshConstructor =
  363. makeMethodGen(currentClass, newConstructorMember);
  364. currentClass.addMethodGen(freshConstructor);
  365. //weaver.addLazyMethodGen(freshConstructor);
  366. InstructionList body = freshConstructor.getBody();
  367. // add to body: push arts for call to pre, from actual args starting at 1 (skipping this), going to
  368. // declared argcount + 1
  369. TypeX[] declaredParams = newConstructorTypeMunger.getSignature().getParameterTypes();
  370. Type[] paramTypes = freshConstructor.getArgumentTypes();
  371. int frameIndex = 1;
  372. for (int i = 0, len = declaredParams.length; i < len; i++) {
  373. body.append(fact.createLoad(paramTypes[i], frameIndex));
  374. frameIndex += paramTypes[i].getSize();
  375. }
  376. // do call to pre
  377. Member preMethod = AjcMemberMaker.preIntroducedConstructor(aspectType, onType, declaredParams);
  378. body.append(Utility.createInvoke(fact, null, preMethod));
  379. // create a local, and store return pre stuff into it.
  380. int arraySlot = freshConstructor.allocateLocal(1);
  381. body.append(fact.createStore(Type.OBJECT, arraySlot));
  382. // put this on the stack
  383. body.append(fact.ALOAD_0);
  384. // unpack pre args onto stack
  385. TypeX[] superParamTypes = explicitConstructor.getParameterTypes();
  386. for (int i = 0, len = superParamTypes.length; i < len; i++) {
  387. body.append(fact.createLoad(Type.OBJECT, arraySlot));
  388. body.append(Utility.createConstant(fact, i));
  389. body.append(fact.createArrayLoad(Type.OBJECT));
  390. body.append(Utility.createConversion(fact, Type.OBJECT, BcelWorld.makeBcelType(superParamTypes[i])));
  391. }
  392. // call super/this
  393. body.append(Utility.createInvoke(fact, null, explicitConstructor));
  394. // put this back on the stack
  395. body.append(fact.ALOAD_0);
  396. // unpack params onto stack
  397. Member postMethod = AjcMemberMaker.postIntroducedConstructor(aspectType, onType, declaredParams);
  398. TypeX[] postParamTypes = postMethod.getParameterTypes();
  399. for (int i = 1, len = postParamTypes.length; i < len; i++) {
  400. body.append(fact.createLoad(Type.OBJECT, arraySlot));
  401. body.append(Utility.createConstant(fact, superParamTypes.length + i-1));
  402. body.append(fact.createArrayLoad(Type.OBJECT));
  403. body.append(Utility.createConversion(fact, Type.OBJECT, BcelWorld.makeBcelType(postParamTypes[i])));
  404. }
  405. // call post
  406. body.append(Utility.createInvoke(fact, null, postMethod));
  407. // don't forget to return!!
  408. body.append(fact.RETURN);
  409. return true;
  410. }
  411. private static LazyMethodGen makeDispatcher(
  412. LazyClassGen onGen,
  413. String dispatchName,
  414. ResolvedMember superMethod,
  415. BcelWorld world,
  416. boolean isSuper)
  417. {
  418. Type[] paramTypes = BcelWorld.makeBcelTypes(superMethod.getParameterTypes());
  419. Type returnType = BcelWorld.makeBcelType(superMethod.getReturnType());
  420. int modifiers = Modifier.PUBLIC;
  421. if (onGen.isInterface()) modifiers |= Modifier.ABSTRACT;
  422. LazyMethodGen mg =
  423. new LazyMethodGen(
  424. modifiers,
  425. returnType,
  426. dispatchName,
  427. paramTypes,
  428. TypeX.getNames(superMethod.getExceptions()),
  429. onGen);
  430. InstructionList body = mg.getBody();
  431. if (onGen.isInterface()) return mg;
  432. // assert (!superMethod.isStatic())
  433. InstructionFactory fact = onGen.getFactory();
  434. int pos = 0;
  435. body.append(fact.createThis());
  436. pos++;
  437. for (int i = 0, len = paramTypes.length; i < len; i++) {
  438. Type paramType = paramTypes[i];
  439. body.append(fact.createLoad(paramType, pos));
  440. pos+=paramType.getSize();
  441. }
  442. if (isSuper) {
  443. body.append(Utility.createSuperInvoke(fact, world, superMethod));
  444. } else {
  445. body.append(Utility.createInvoke(fact, world, superMethod));
  446. }
  447. body.append(fact.createReturn(returnType));
  448. return mg;
  449. }
  450. private boolean mungeNewField(BcelClassWeaver weaver, NewFieldTypeMunger munger) {
  451. ResolvedMember initMethod = munger.getInitMethod(aspectType);
  452. LazyClassGen gen = weaver.getLazyClassGen();
  453. ResolvedMember field = munger.getSignature();
  454. ResolvedTypeX onType = weaver.getWorld().resolve(field.getDeclaringType());
  455. boolean onInterface = onType.isInterface();
  456. if (onType.equals(gen.getType())) {
  457. if (onInterface) {
  458. LazyMethodGen mg = makeMethodGen(gen,
  459. AjcMemberMaker.interFieldInterfaceGetter(field, onType, aspectType));
  460. gen.addMethodGen(mg);
  461. LazyMethodGen mg1 = makeMethodGen(gen,
  462. AjcMemberMaker.interFieldInterfaceSetter(field, onType, aspectType));
  463. gen.addMethodGen(mg1);
  464. } else {
  465. weaver.addInitializer(this);
  466. FieldGen fg = makeFieldGen(gen,
  467. AjcMemberMaker.interFieldClassField(field, aspectType));
  468. gen.addField(fg.getField());
  469. }
  470. return true;
  471. } else if (onInterface && gen.getType().isTopmostImplementor(onType)) {
  472. // wew know that we can't be static since we don't allow statics on interfaces
  473. if (field.isStatic()) throw new RuntimeException("unimplemented");
  474. weaver.addInitializer(this);
  475. //System.err.println("impl body on " + gen.getType() + " for " + munger);
  476. Type fieldType = BcelWorld.makeBcelType(field.getType());
  477. FieldGen fg = makeFieldGen(gen,
  478. AjcMemberMaker.interFieldInterfaceField(field, onType, aspectType));
  479. gen.addField(fg.getField());
  480. //this uses a shadow munger to add init method to constructors
  481. //weaver.getShadowMungers().add(makeInitCallShadowMunger(initMethod));
  482. LazyMethodGen mg = makeMethodGen(gen,
  483. AjcMemberMaker.interFieldInterfaceGetter(field, gen.getType(), aspectType));
  484. InstructionList il = new InstructionList();
  485. InstructionFactory fact = gen.getFactory();
  486. if (field.isStatic()) {
  487. il.append(fact.createFieldAccess(
  488. gen.getClassName(),
  489. fg.getName(),
  490. fieldType, Constants.GETSTATIC));
  491. } else {
  492. il.append(fact.ALOAD_0);
  493. il.append(fact.createFieldAccess(
  494. gen.getClassName(),
  495. fg.getName(),
  496. fieldType, Constants.GETFIELD));
  497. }
  498. il.append(fact.createReturn(fieldType));
  499. mg.getBody().insert(il);
  500. gen.addMethodGen(mg);
  501. LazyMethodGen mg1 = makeMethodGen(gen,
  502. AjcMemberMaker.interFieldInterfaceSetter(field, gen.getType(), aspectType));
  503. InstructionList il1 = new InstructionList();
  504. if (field.isStatic()) {
  505. il1.append(fact.createLoad(fieldType, 0));
  506. il1.append(fact.createFieldAccess(
  507. gen.getClassName(),
  508. fg.getName(),
  509. fieldType, Constants.PUTSTATIC));
  510. } else {
  511. il1.append(fact.ALOAD_0);
  512. il1.append(fact.createLoad(fieldType, 1));
  513. il1.append(fact.createFieldAccess(
  514. gen.getClassName(),
  515. fg.getName(),
  516. fieldType, Constants.PUTFIELD));
  517. }
  518. il1.append(fact.createReturn(Type.VOID));
  519. mg1.getBody().insert(il1);
  520. gen.addMethodGen(mg1);
  521. return true;
  522. } else {
  523. return false;
  524. }
  525. }
  526. }