* Specific state and logic is kept in the munger ala ITD so that call/get/set pointcuts can still be matched on the wrapped member
* thanks to the EffectiveSignature attribute.
*
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ * @author Alexandre Vasseur
+ * @author Andy Clement
*/
public class BcelAccessForInlineMunger extends BcelTypeMunger {
- /**
- * Wrapper member cache, key is wrapper name. This structure is queried when regular shadow matching in the advice body
- * (call/get/set) occurs
- */
- private Map<String, ResolvedMember> m_inlineAccessorBcelMethods;
+ private Map<String, ResolvedMember> inlineAccessors;
- /**
- * The aspect we act for
- */
- private LazyClassGen m_aspectGen;
+ private LazyClassGen aspectGen;
/**
- * The wrapper method we need to add. Those are added at the end of the munging
+ * The wrapper methods representing any created inlineAccessors
*/
private Set<LazyMethodGen> inlineAccessorMethodGens;
@Override
public boolean munge(BcelClassWeaver weaver) {
- m_aspectGen = weaver.getLazyClassGen();
- m_inlineAccessorBcelMethods = new HashMap<String, ResolvedMember>(0);
+ aspectGen = weaver.getLazyClassGen();
+ inlineAccessors = new HashMap<String, ResolvedMember>(0);
inlineAccessorMethodGens = new HashSet<LazyMethodGen>();
// look for all @Around advices
- for (LazyMethodGen methodGen : m_aspectGen.getMethodGens()) {
+ for (LazyMethodGen methodGen : aspectGen.getMethodGens()) {
if (methodGen.hasAnnotation(UnresolvedType.forName("org/aspectj/lang/annotation/Around"))) {
openAroundAdvice(methodGen);
}
// add the accessors
for (LazyMethodGen lazyMethodGen : inlineAccessorMethodGens) {
- m_aspectGen.addMethodGen(lazyMethodGen);
+ aspectGen.addMethodGen(lazyMethodGen);
}
// flush some
/**
* Looks in the wrapper we have added so that we can find their effective signature if needed
- *
- * @param member
- * @return
*/
@Override
public ResolvedMember getMatchingSyntheticMember(Member member) {
- return m_inlineAccessorBcelMethods.get(member.getName());
+ ResolvedMember rm = inlineAccessors.get(member.getName());// + member.getSignature());
+// System.err.println("lookup for " + member.getName() + ":" + member.getSignature() + " = "
+// + (rm == null ? "" : rm.getName()));
+ return rm;
}
@Override
/**
* Match only the aspect for which we act
- *
- * @param onType
- * @return
*/
@Override
public boolean matches(ResolvedType onType) {
/**
* Prepare the around advice, flag it as cannot be inlined if it can't be
- *
- * @param aroundAdvice
*/
private void openAroundAdvice(LazyMethodGen aroundAdvice) {
InstructionHandle curr = aroundAdvice.getBody().getStart();
// open-up method call
if ((inst instanceof InvokeInstruction)) {
InvokeInstruction invoke = (InvokeInstruction) inst;
- ResolvedType callee = m_aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg)));
+ ResolvedType callee = aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg)));
// look in the whole method list and not just declared for super calls and alike
List<ResolvedMember> methods = callee.getMethodsWithoutIterator(false, true, false);
realizedCannotInline = true;
} else {
// specific handling for super.foo() calls, where foo is non public
- ResolvedType memberType = m_aspectGen.getWorld().resolve(resolvedMember.getDeclaringType());
+ ResolvedType memberType = aspectGen.getWorld().resolve(resolvedMember.getDeclaringType());
if (!aspectType.equals(memberType) && memberType.isAssignableFrom(aspectType)) {
// old test was...
// if (aspectType.getSuperclass() != null
}
} else if (inst instanceof FieldInstruction) {
FieldInstruction invoke = (FieldInstruction) inst;
- ResolvedType callee = m_aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg)));
+ ResolvedType callee = aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg)));
for (int i = 0; i < callee.getDeclaredJavaFields().length; i++) {
ResolvedMember resolvedMember = callee.getDeclaredJavaFields()[i];
if (invoke.getName(cpg).equals(resolvedMember.getName())
}
/**
- * Add an inline wrapper for a non public method call
- *
- * @param resolvedMember
- * @return
+ * Find (or add if not yet created) an inline wrapper for a non public method call
*/
private ResolvedMember createOrGetInlineAccessorForMethod(ResolvedMember resolvedMember) {
- String accessor = NameMangler.inlineAccessMethodForMethod(resolvedMember.getName(), resolvedMember.getDeclaringType(),
+ String accessorName = NameMangler.inlineAccessMethodForMethod(resolvedMember.getName(), resolvedMember.getDeclaringType(),
aspectType);
- ResolvedMember inlineAccessor = m_inlineAccessorBcelMethods.get(accessor);
+ String key = accessorName;// new StringBuilder(accessorName).append(resolvedMember.getSignature()).toString();
+ ResolvedMember inlineAccessor = inlineAccessors.get(key);
+// System.err.println(key + " accessor=" + inlineAccessor);
if (inlineAccessor == null) {
// add static method to aspect
inlineAccessor = AjcMemberMaker.inlineAccessMethodForMethod(aspectType, resolvedMember);
// add new accessor method to aspect bytecode
- InstructionFactory factory = m_aspectGen.getFactory();
- LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
- // flag it synthetic, AjSynthetic
+ InstructionFactory factory = aspectGen.getFactory();
+ LazyMethodGen method = makeMethodGen(aspectGen, inlineAccessor);
method.makeSynthetic();
List<AjAttribute> methodAttributes = new ArrayList<AjAttribute>();
methodAttributes.add(new AjAttribute.AjSynthetic());
methodAttributes.add(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false));
- method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), aspectGen.getConstantPool()));
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
- method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), aspectGen.getConstantPool()));
inlineAccessorMethodGens.add(method);
InstructionList il = method.getBody();
int register = 0;
- for (int i = 0; i < inlineAccessor.getParameterTypes().length; i++) {
- UnresolvedType typeX = inlineAccessor.getParameterTypes()[i];
- Type type = BcelWorld.makeBcelType(typeX);
+ for (int i = 0, max = inlineAccessor.getParameterTypes().length; i < max; i++) {
+ UnresolvedType ptype = inlineAccessor.getParameterTypes()[i];
+ Type type = BcelWorld.makeBcelType(ptype);
il.append(InstructionFactory.createLoad(type, register));
register += type.getSize();
}
: Constants.INVOKEVIRTUAL, resolvedMember));
il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(inlineAccessor.getReturnType())));
- m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod(),
- methodAttributes));
+ inlineAccessors.put(key, new BcelMethod(aspectGen.getBcelObjectType(), method.getMethod(), methodAttributes));
}
return inlineAccessor;
}
/**
* Add an inline wrapper for a non public super.method call
- *
- * @param resolvedMember
- * @return
*/
private ResolvedMember createOrGetInlineAccessorForSuperDispatch(ResolvedMember resolvedMember) {
String accessor = NameMangler.superDispatchMethod(aspectType, resolvedMember.getName());
- ResolvedMember inlineAccessor = m_inlineAccessorBcelMethods.get(accessor);
+
+ String key = accessor;
+ ResolvedMember inlineAccessor = inlineAccessors.get(key);
+
if (inlineAccessor == null) {
// add super accessor method to class:
inlineAccessor = AjcMemberMaker.superAccessMethod(aspectType, resolvedMember);
// add new accessor method to aspect bytecode
- InstructionFactory factory = m_aspectGen.getFactory();
- LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
+ InstructionFactory factory = aspectGen.getFactory();
+ LazyMethodGen method = makeMethodGen(aspectGen, inlineAccessor);
// flag it synthetic, AjSynthetic
method.makeSynthetic();
List<AjAttribute> methodAttributes = new ArrayList<AjAttribute>();
methodAttributes.add(new AjAttribute.AjSynthetic());
methodAttributes.add(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false));
- method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), aspectGen.getConstantPool()));
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
- method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), aspectGen.getConstantPool()));
inlineAccessorMethodGens.add(method);
il.append(Utility.createInvoke(factory, Constants.INVOKESPECIAL, resolvedMember));
il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(inlineAccessor.getReturnType())));
- m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod(),
- methodAttributes));
+ inlineAccessors.put(key, new BcelMethod(aspectGen.getBcelObjectType(), method.getMethod(), methodAttributes));
}
return inlineAccessor;
}
/**
* Add an inline wrapper for a non public field get
- *
- * @param resolvedMember
- * @return
*/
private ResolvedMember createOrGetInlineAccessorForFieldGet(ResolvedMember resolvedMember) {
String accessor = NameMangler.inlineAccessMethodForFieldGet(resolvedMember.getName(), resolvedMember.getDeclaringType(),
aspectType);
- ResolvedMember inlineAccessor = m_inlineAccessorBcelMethods.get(accessor);
+ String key = accessor;
+ ResolvedMember inlineAccessor = inlineAccessors.get(key);
+
if (inlineAccessor == null) {
// add static method to aspect
inlineAccessor = AjcMemberMaker.inlineAccessMethodForFieldGet(aspectType, resolvedMember);
// add new accessor method to aspect bytecode
- InstructionFactory factory = m_aspectGen.getFactory();
- LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
+ InstructionFactory factory = aspectGen.getFactory();
+ LazyMethodGen method = makeMethodGen(aspectGen, inlineAccessor);
// flag it synthetic, AjSynthetic
method.makeSynthetic();
List<AjAttribute> methodAttributes = new ArrayList<AjAttribute>();
methodAttributes.add(new AjAttribute.AjSynthetic());
methodAttributes.add(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet, false));
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
- method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), m_aspectGen.getConstantPool()));
- method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), aspectGen.getConstantPool()));
inlineAccessorMethodGens.add(method);
il.append(Utility.createGet(factory, resolvedMember));
il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(inlineAccessor.getReturnType())));
- m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod(),
- methodAttributes));
+ inlineAccessors.put(key, new BcelMethod(aspectGen.getBcelObjectType(), method.getMethod(), methodAttributes));
}
return inlineAccessor;
}
/**
* Add an inline wrapper for a non public field set
- *
- * @param resolvedMember
- * @return
*/
private ResolvedMember createOrGetInlineAccessorForFieldSet(ResolvedMember resolvedMember) {
String accessor = NameMangler.inlineAccessMethodForFieldSet(resolvedMember.getName(), resolvedMember.getDeclaringType(),
aspectType);
- ResolvedMember inlineAccessor = m_inlineAccessorBcelMethods.get(accessor);
+ String key = accessor;
+ ResolvedMember inlineAccessor = inlineAccessors.get(key);
+
if (inlineAccessor == null) {
// add static method to aspect
inlineAccessor = AjcMemberMaker.inlineAccessMethodForFieldSet(aspectType, resolvedMember);
// add new accessor method to aspect bytecode
- InstructionFactory factory = m_aspectGen.getFactory();
- LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
+ InstructionFactory factory = aspectGen.getFactory();
+ LazyMethodGen method = makeMethodGen(aspectGen, inlineAccessor);
// flag it synthetic, AjSynthetic
method.makeSynthetic();
List<AjAttribute> methodAttributes = new ArrayList<AjAttribute>();
methodAttributes.add(new AjAttribute.AjSynthetic());
methodAttributes.add(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet, false));
- method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), aspectGen.getConstantPool()));
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
- method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), aspectGen.getConstantPool()));
inlineAccessorMethodGens.add(method);
}
il.append(Utility.createSet(factory, resolvedMember));
il.append(InstructionConstants.RETURN);
- m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod(),
- methodAttributes));
+ inlineAccessors.put(key, new BcelMethod(aspectGen.getBcelObjectType(), method.getMethod(), methodAttributes));
}
return inlineAccessor;
}