]> source.dussan.org Git - aspectj.git/commitdiff
252722: test and fix: generated super dispatch methods
authoraclement <aclement>
Mon, 15 Dec 2008 21:28:29 +0000 (21:28 +0000)
committeraclement <aclement>
Mon, 15 Dec 2008 21:28:29 +0000 (21:28 +0000)
weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java

index 299235176331bb0f8e89418084b2972f9085e996..f7030cedb0feafd35f0609a39aeb6510fd4a0a26 100644 (file)
  *******************************************************************************/
 package org.aspectj.weaver.bcel;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.aspectj.apache.bcel.Constants;
 import org.aspectj.apache.bcel.classfile.ConstantPool;
 import org.aspectj.apache.bcel.generic.FieldInstruction;
@@ -30,447 +37,351 @@ import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.UnresolvedType;
 
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.List;
-
 /**
- * Looks for all access to method or field that are not public within the body of the around advices and replace
- * the invocations to a wrapper call so that the around advice can further be inlined.
+ * Looks for all access to method or field that are not public within the body of the around advices and replace the invocations to
+ * a wrapper call so that the around advice can further be inlined.
  * <p/>
  * This munger is used for @AJ aspects for which inlining wrapper is not done at compile time.
  * <p/>
- * 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.
- *
+ * 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>
  */
 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 m_inlineAccessorBcelMethods;
-
-    /**
-     * The aspect we act for
-     */
-    private LazyClassGen m_aspectGen;
-
-    /**
-     * The wrapper method we need to add. Those are added at the end of the munging
-     */
-    private Set m_inlineAccessorMethodGens;
-
-    public BcelAccessForInlineMunger(ResolvedType aspectType) {
-        super(null, aspectType);
-        if (aspectType.getWorld().isXnoInline()) {
-            throw new Error("This should not happen");
-        }
-    }
-
-    public boolean munge(BcelClassWeaver weaver) {
-        m_aspectGen = weaver.getLazyClassGen();
-        m_inlineAccessorBcelMethods = new HashMap(0);
-        m_inlineAccessorMethodGens = new HashSet();
-
-        // look for all @Around advices
-        for (Iterator iterator = m_aspectGen.getMethodGens().iterator(); iterator.hasNext();) {
-            LazyMethodGen methodGen = (LazyMethodGen) iterator.next();
-            if (methodGen.hasAnnotation(UnresolvedType.forName("org/aspectj/lang/annotation/Around"))) {
-                openAroundAdvice(methodGen);
-            }
-        }
-
-        // add the accessors
-        for (Iterator iterator = m_inlineAccessorMethodGens.iterator(); iterator.hasNext();) {
-            LazyMethodGen lazyMethodGen = (LazyMethodGen) iterator.next();
-            m_aspectGen.addMethodGen(lazyMethodGen);
-        }
-
-        // flush some
-        m_inlineAccessorMethodGens = null;
-        // we keep m_inlineAccessorsResolvedMembers for shadow matching
-
-        return true;
-    }
-
-    /**
-     * Looks in the wrapper we have added so that we can find their effective signature if needed
-     *
-     * @param member
-     * @return
-     */
-    public ResolvedMember getMatchingSyntheticMember(Member member) {
-        return (ResolvedMember) m_inlineAccessorBcelMethods.get(member.getName());
-    }
-
-    public ResolvedMember getSignature() {
-        return null;
-    }
-
-    /**
-     * Match only the aspect for which we act
-     *
-     * @param onType
-     * @return
-     */
-    public boolean matches(ResolvedType onType) {
-        return aspectType.equals(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();
-        InstructionHandle end = aroundAdvice.getBody().getEnd();
-        ConstantPool cpg = aroundAdvice.getEnclosingClass().getConstantPool();
-        InstructionFactory factory = aroundAdvice.getEnclosingClass().getFactory();
-
-        boolean realizedCannotInline = false;
-        while (curr != end) {
-            if (realizedCannotInline) {
-                // we know we cannot inline this advice so no need for futher handling
-                break;
-            }
-            InstructionHandle next = curr.getNext();
-            Instruction inst = curr.getInstruction();
-
-            // open-up method call
-            if ((inst instanceof InvokeInstruction)) {
-                InvokeInstruction invoke = (InvokeInstruction) inst;
-                ResolvedType callee = m_aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg)));
-
-                // look in the whole method list and not just declared for super calls and alike
-                List methods = callee.getMethodsWithoutIterator(false,true);
-                for (Iterator iter = methods.iterator(); iter.hasNext();) {
-                    ResolvedMember resolvedMember = (ResolvedMember) iter.next();
-                    if (invoke.getName(cpg).equals(resolvedMember.getName())
-                            && invoke.getSignature(cpg).equals(resolvedMember.getSignature())
-                            && !resolvedMember.isPublic()) {
-                        if ("<init>".equals(invoke.getName(cpg))) {
-                            // skipping open up for private constructor
-                            // can occur when aspect new a private inner type
-                            // too complex to handle new + dup + .. + invokespecial here.
-                            aroundAdvice.setCanInline(false);
-                            realizedCannotInline = true;
-                        } else {
-                            // specific handling for super.foo() calls, where foo is non public
-                               ResolvedType memberType = m_aspectGen.getWorld().resolve(resolvedMember.getDeclaringType());
-                               if (!aspectType.equals(memberType) &&
-                                       memberType.isAssignableFrom(aspectType)) {
-                                       // old test was...
-  //                            if (aspectType.getSuperclass() != null
-  //                                    && aspectType.getSuperclass().getName().equals(resolvedMember.getDeclaringType().getName())) {
-                                ResolvedMember accessor = createOrGetInlineAccessorForSuperDispatch(resolvedMember);
-                                InvokeInstruction newInst = factory.createInvoke(
-                                        aspectType.getName(),
-                                        accessor.getName(),
-                                        BcelWorld.makeBcelType(accessor.getReturnType()),
-                                        BcelWorld.makeBcelTypes(accessor.getParameterTypes()),
-                                        Constants.INVOKEVIRTUAL
-                                );
-                                curr.setInstruction(newInst);
-                            } else {
-                                ResolvedMember accessor = createOrGetInlineAccessorForMethod(resolvedMember);
-                                InvokeInstruction newInst = factory.createInvoke(
-                                        aspectType.getName(),
-                                        accessor.getName(),
-                                        BcelWorld.makeBcelType(accessor.getReturnType()),
-                                        BcelWorld.makeBcelTypes(accessor.getParameterTypes()),
-                                        Constants.INVOKESTATIC
-                                );
-                                curr.setInstruction(newInst);
-                            }
-                        }
-
-                        break;//ok we found a matching callee member and swapped the instruction with the accessor
-                    }
-                }
-            } else if (inst instanceof FieldInstruction) {
-                FieldInstruction invoke = (FieldInstruction) inst;
-                ResolvedType callee = m_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())
-                            && invoke.getSignature(cpg).equals(resolvedMember.getSignature())
-                            && !resolvedMember.isPublic()) {
-                        final ResolvedMember accessor;
-                        if ((inst.opcode==Constants.GETFIELD) || (inst.opcode==Constants.GETSTATIC)) {
-                            accessor = createOrGetInlineAccessorForFieldGet(resolvedMember);
-                        } else {
-                            accessor = createOrGetInlineAccessorForFieldSet(resolvedMember);
-                        }
-                        InvokeInstruction newInst = factory.createInvoke(
-                                aspectType.getName(),
-                                accessor.getName(),
-                                BcelWorld.makeBcelType(accessor.getReturnType()),
-                                BcelWorld.makeBcelTypes(accessor.getParameterTypes()),
-                                Constants.INVOKESTATIC
-                        );
-                        curr.setInstruction(newInst);
-
-                        break;//ok we found a matching callee member and swapped the instruction with the accessor
-                    }
-                }
-            }
-
-            curr = next;
-        }
-
-        // no reason for not inlining this advice
-        // since it is used for @AJ advice that cannot be inlined by defauilt
-        // make sure we set inline to true since we have done this analysis
-        if (!realizedCannotInline) {
-            aroundAdvice.setCanInline(true);
-        }
-    }
-
-    /**
-     * Add an inline wrapper for a non public method call
-     *
-     * @param resolvedMember
-     * @return
-     */
-    private ResolvedMember createOrGetInlineAccessorForMethod(ResolvedMember resolvedMember) {
-        String accessor = NameMangler.inlineAccessMethodForMethod(
-                resolvedMember.getName(), resolvedMember.getDeclaringType(), aspectType
-        );
-        ResolvedMember inlineAccessor = (ResolvedMember) m_inlineAccessorBcelMethods.get(accessor);
-        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
-            method.makeSynthetic();
-            method.addAttribute(
-                    Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
-            );
-            // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
-            method.addAttribute(
-                    Utility.bcelAttribute(
-                            new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false),
-                            m_aspectGen.getConstantPool()
-                    )
-            );
-
-            m_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);
-                il.append(InstructionFactory.createLoad(type, register));
-                register += type.getSize();
-            }
-            il.append(
-                    Utility.createInvoke(
-                            factory,
-                            resolvedMember.isStatic() ? Constants.INVOKESTATIC : Constants.INVOKESPECIAL,
-                            resolvedMember
-                    )
-            );
-            il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(inlineAccessor.getReturnType())));
-
-            m_inlineAccessorBcelMethods.put(
-                    accessor,
-                    new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod())
-            );
-        }
-        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 = (ResolvedMember) m_inlineAccessorBcelMethods.get(accessor);
-        if (inlineAccessor == null) {
-            // add static method to aspect
-            inlineAccessor = AjcMemberMaker.superAccessMethod(
-                    aspectType,
-                    resolvedMember
-            );
-
-            //add new accessor method to aspect bytecode
-            InstructionFactory factory = m_aspectGen.getFactory();
-            LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
-            // flag it synthetic, AjSynthetic
-            method.makeSynthetic();
-            method.addAttribute(
-                    Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
-            );
-            // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
-            method.addAttribute(
-                    Utility.bcelAttribute(
-                            new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false),
-                            m_aspectGen.getConstantPool()
-                    )
-            );
-
-            m_inlineAccessorMethodGens.add(method);
-
-            InstructionList il = method.getBody();
-            il.append(InstructionConstants.ALOAD_0);
-            int register = 0;
-            for (int i = 0; i < inlineAccessor.getParameterTypes().length; i++) {
-                UnresolvedType typeX = inlineAccessor.getParameterTypes()[i];
-                Type type = BcelWorld.makeBcelType(typeX);
-                il.append(InstructionFactory.createLoad(type, register));
-                register += type.getSize();
-            }
-            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())
-            );
-        }
-        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 = (ResolvedMember) m_inlineAccessorBcelMethods.get(accessor);
-        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);
-            // flag it synthetic, AjSynthetic
-            method.makeSynthetic();
-            method.addAttribute(
-                    Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
-            );
-            // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
-            method.addAttribute(
-                    Utility.bcelAttribute(
-                            new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet, false),
-                            m_aspectGen.getConstantPool()
-                    )
-            );
-
-            m_inlineAccessorMethodGens.add(method);
-
-            InstructionList il = method.getBody();
-            if (resolvedMember.isStatic()) {
-                // field accessed is static so no "this" as accessor sole parameter
-            } else {
-                il.append(InstructionConstants.ALOAD_0);
-            }
-            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())
-            );
-        }
-        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 = (ResolvedMember) m_inlineAccessorBcelMethods.get(accessor);
-        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);
-            // flag it synthetic, AjSynthetic
-            method.makeSynthetic();
-            method.addAttribute(
-                    Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
-            );
-            // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
-            method.addAttribute(
-                    Utility.bcelAttribute(
-                            new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet, false),
-                            m_aspectGen.getConstantPool()
-                    )
-            );
-
-            m_inlineAccessorMethodGens.add(method);
-
-            InstructionList il = method.getBody();
-            if (resolvedMember.isStatic()) {
-                // field accessed is static so sole parameter is field value to be set
-                il.append(InstructionFactory.createLoad(BcelWorld.makeBcelType(resolvedMember.getReturnType()), 0));
-            } else {
-                il.append(InstructionConstants.ALOAD_0);
-                il.append(InstructionFactory.createLoad(BcelWorld.makeBcelType(resolvedMember.getReturnType()), 1));
-            }
-            il.append(
-                    Utility.createSet(
-                            factory,
-                            resolvedMember
-                    )
-            );
-            il.append(InstructionConstants.RETURN);
-
-            m_inlineAccessorBcelMethods.put(
-                    accessor,
-                    new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod())
-            );
-        }
-        return inlineAccessor;
-    }
+       /**
+        * 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 m_inlineAccessorBcelMethods;
+
+       /**
+        * The aspect we act for
+        */
+       private LazyClassGen m_aspectGen;
+
+       /**
+        * The wrapper method we need to add. Those are added at the end of the munging
+        */
+       private Set m_inlineAccessorMethodGens;
+
+       public BcelAccessForInlineMunger(ResolvedType aspectType) {
+               super(null, aspectType);
+               if (aspectType.getWorld().isXnoInline()) {
+                       throw new Error("This should not happen");
+               }
+       }
+
+       public boolean munge(BcelClassWeaver weaver) {
+               m_aspectGen = weaver.getLazyClassGen();
+               m_inlineAccessorBcelMethods = new HashMap(0);
+               m_inlineAccessorMethodGens = new HashSet();
+
+               // look for all @Around advices
+               for (Iterator iterator = m_aspectGen.getMethodGens().iterator(); iterator.hasNext();) {
+                       LazyMethodGen methodGen = (LazyMethodGen) iterator.next();
+                       if (methodGen.hasAnnotation(UnresolvedType.forName("org/aspectj/lang/annotation/Around"))) {
+                               openAroundAdvice(methodGen);
+                       }
+               }
+
+               // add the accessors
+               for (Iterator iterator = m_inlineAccessorMethodGens.iterator(); iterator.hasNext();) {
+                       LazyMethodGen lazyMethodGen = (LazyMethodGen) iterator.next();
+                       m_aspectGen.addMethodGen(lazyMethodGen);
+               }
+
+               // flush some
+               m_inlineAccessorMethodGens = null;
+               // we keep m_inlineAccessorsResolvedMembers for shadow matching
+
+               return true;
+       }
+
+       /**
+        * Looks in the wrapper we have added so that we can find their effective signature if needed
+        * 
+        * @param member
+        * @return
+        */
+       public ResolvedMember getMatchingSyntheticMember(Member member) {
+               return (ResolvedMember) m_inlineAccessorBcelMethods.get(member.getName());
+       }
+
+       public ResolvedMember getSignature() {
+               return null;
+       }
+
+       /**
+        * Match only the aspect for which we act
+        * 
+        * @param onType
+        * @return
+        */
+       public boolean matches(ResolvedType onType) {
+               return aspectType.equals(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();
+               InstructionHandle end = aroundAdvice.getBody().getEnd();
+               ConstantPool cpg = aroundAdvice.getEnclosingClass().getConstantPool();
+               InstructionFactory factory = aroundAdvice.getEnclosingClass().getFactory();
+
+               boolean realizedCannotInline = false;
+               while (curr != end) {
+                       if (realizedCannotInline) {
+                               // we know we cannot inline this advice so no need for futher handling
+                               break;
+                       }
+                       InstructionHandle next = curr.getNext();
+                       Instruction inst = curr.getInstruction();
+
+                       // open-up method call
+                       if ((inst instanceof InvokeInstruction)) {
+                               InvokeInstruction invoke = (InvokeInstruction) inst;
+                               ResolvedType callee = m_aspectGen.getWorld().resolve(UnresolvedType.forName(invoke.getClassName(cpg)));
+
+                               // look in the whole method list and not just declared for super calls and alike
+                               List methods = callee.getMethodsWithoutIterator(false, true);
+                               for (Iterator iter = methods.iterator(); iter.hasNext();) {
+                                       ResolvedMember resolvedMember = (ResolvedMember) iter.next();
+                                       if (invoke.getName(cpg).equals(resolvedMember.getName())
+                                                       && invoke.getSignature(cpg).equals(resolvedMember.getSignature()) && !resolvedMember.isPublic()) {
+                                               if ("<init>".equals(invoke.getName(cpg))) {
+                                                       // skipping open up for private constructor
+                                                       // can occur when aspect new a private inner type
+                                                       // too complex to handle new + dup + .. + invokespecial here.
+                                                       aroundAdvice.setCanInline(false);
+                                                       realizedCannotInline = true;
+                                               } else {
+                                                       // specific handling for super.foo() calls, where foo is non public
+                                                       ResolvedType memberType = m_aspectGen.getWorld().resolve(resolvedMember.getDeclaringType());
+                                                       if (!aspectType.equals(memberType) && memberType.isAssignableFrom(aspectType)) {
+                                                               // old test was...
+                                                               // if (aspectType.getSuperclass() != null
+                                                               // && aspectType.getSuperclass().getName().equals(resolvedMember.getDeclaringType().getName())) {
+                                                               ResolvedMember accessor = createOrGetInlineAccessorForSuperDispatch(resolvedMember);
+                                                               InvokeInstruction newInst = factory.createInvoke(aspectType.getName(), accessor.getName(),
+                                                                               BcelWorld.makeBcelType(accessor.getReturnType()), BcelWorld.makeBcelTypes(accessor
+                                                                                               .getParameterTypes()), Constants.INVOKEVIRTUAL);
+                                                               curr.setInstruction(newInst);
+                                                       } else {
+                                                               ResolvedMember accessor = createOrGetInlineAccessorForMethod(resolvedMember);
+                                                               InvokeInstruction newInst = factory.createInvoke(aspectType.getName(), accessor.getName(),
+                                                                               BcelWorld.makeBcelType(accessor.getReturnType()), BcelWorld.makeBcelTypes(accessor
+                                                                                               .getParameterTypes()), Constants.INVOKESTATIC);
+                                                               curr.setInstruction(newInst);
+                                                       }
+                                               }
+
+                                               break;// ok we found a matching callee member and swapped the instruction with the accessor
+                                       }
+                               }
+                       } else if (inst instanceof FieldInstruction) {
+                               FieldInstruction invoke = (FieldInstruction) inst;
+                               ResolvedType callee = m_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())
+                                                       && invoke.getSignature(cpg).equals(resolvedMember.getSignature()) && !resolvedMember.isPublic()) {
+                                               final ResolvedMember accessor;
+                                               if ((inst.opcode == Constants.GETFIELD) || (inst.opcode == Constants.GETSTATIC)) {
+                                                       accessor = createOrGetInlineAccessorForFieldGet(resolvedMember);
+                                               } else {
+                                                       accessor = createOrGetInlineAccessorForFieldSet(resolvedMember);
+                                               }
+                                               InvokeInstruction newInst = factory.createInvoke(aspectType.getName(), accessor.getName(), BcelWorld
+                                                               .makeBcelType(accessor.getReturnType()), BcelWorld.makeBcelTypes(accessor.getParameterTypes()),
+                                                               Constants.INVOKESTATIC);
+                                               curr.setInstruction(newInst);
+
+                                               break;// ok we found a matching callee member and swapped the instruction with the accessor
+                                       }
+                               }
+                       }
+
+                       curr = next;
+               }
+
+               // no reason for not inlining this advice
+               // since it is used for @AJ advice that cannot be inlined by defauilt
+               // make sure we set inline to true since we have done this analysis
+               if (!realizedCannotInline) {
+                       aroundAdvice.setCanInline(true);
+               }
+       }
+
+       /**
+        * Add an inline wrapper for a non public method call
+        * 
+        * @param resolvedMember
+        * @return
+        */
+       private ResolvedMember createOrGetInlineAccessorForMethod(ResolvedMember resolvedMember) {
+               String accessor = NameMangler.inlineAccessMethodForMethod(resolvedMember.getName(), resolvedMember.getDeclaringType(),
+                               aspectType);
+               ResolvedMember inlineAccessor = (ResolvedMember) m_inlineAccessorBcelMethods.get(accessor);
+               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
+                       method.makeSynthetic();
+                       method.addAttribute(Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()));
+                       // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
+                       method.addAttribute(Utility.bcelAttribute(new AjAttribute.EffectiveSignatureAttribute(resolvedMember,
+                                       Shadow.MethodCall, false), m_aspectGen.getConstantPool()));
+
+                       m_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);
+                               il.append(InstructionFactory.createLoad(type, register));
+                               register += type.getSize();
+                       }
+                       il.append(Utility.createInvoke(factory, resolvedMember.isStatic() ? Constants.INVOKESTATIC : Constants.INVOKESPECIAL,
+                                       resolvedMember));
+                       il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(inlineAccessor.getReturnType())));
+
+                       m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod()));
+               }
+               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 = (ResolvedMember) m_inlineAccessorBcelMethods.get(accessor);
+               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);
+                       // flag it synthetic, AjSynthetic
+                       method.makeSynthetic();
+                       method.addAttribute(Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()));
+                       // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
+                       method.addAttribute(Utility.bcelAttribute(new AjAttribute.EffectiveSignatureAttribute(resolvedMember,
+                                       Shadow.MethodCall, false), m_aspectGen.getConstantPool()));
+
+                       m_inlineAccessorMethodGens.add(method);
+
+                       InstructionList il = method.getBody();
+                       il.append(InstructionConstants.ALOAD_0);
+                       int register = 1;
+                       for (int i = 0; i < inlineAccessor.getParameterTypes().length; i++) {
+                               UnresolvedType typeX = inlineAccessor.getParameterTypes()[i];
+                               Type type = BcelWorld.makeBcelType(typeX);
+                               il.append(InstructionFactory.createLoad(type, register));
+                               register += type.getSize();
+                       }
+                       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()));
+               }
+               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 = (ResolvedMember) m_inlineAccessorBcelMethods.get(accessor);
+               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);
+                       // flag it synthetic, AjSynthetic
+                       method.makeSynthetic();
+                       method.addAttribute(Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()));
+                       // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
+                       method.addAttribute(Utility.bcelAttribute(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet,
+                                       false), m_aspectGen.getConstantPool()));
+
+                       m_inlineAccessorMethodGens.add(method);
+
+                       InstructionList il = method.getBody();
+                       if (resolvedMember.isStatic()) {
+                               // field accessed is static so no "this" as accessor sole parameter
+                       } else {
+                               il.append(InstructionConstants.ALOAD_0);
+                       }
+                       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()));
+               }
+               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 = (ResolvedMember) m_inlineAccessorBcelMethods.get(accessor);
+               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);
+                       // flag it synthetic, AjSynthetic
+                       method.makeSynthetic();
+                       method.addAttribute(Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()));
+                       // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
+                       method.addAttribute(Utility.bcelAttribute(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet,
+                                       false), m_aspectGen.getConstantPool()));
+
+                       m_inlineAccessorMethodGens.add(method);
+
+                       InstructionList il = method.getBody();
+                       if (resolvedMember.isStatic()) {
+                               // field accessed is static so sole parameter is field value to be set
+                               il.append(InstructionFactory.createLoad(BcelWorld.makeBcelType(resolvedMember.getReturnType()), 0));
+                       } else {
+                               il.append(InstructionConstants.ALOAD_0);
+                               il.append(InstructionFactory.createLoad(BcelWorld.makeBcelType(resolvedMember.getReturnType()), 1));
+                       }
+                       il.append(Utility.createSet(factory, resolvedMember));
+                       il.append(InstructionConstants.RETURN);
+
+                       m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod()));
+               }
+               return inlineAccessor;
+       }
 }