summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2005-04-19 12:41:22 +0000
committeraclement <aclement>2005-04-19 12:41:22 +0000
commit385356c6c19ff2e3f2899a6e4e80ceab5130cc03 (patch)
treeb7137161899b0086f44bfcb96e4129a16350f9ef /weaver
parent7826252fcfcbb10339be57759259f0b4dcb026ee (diff)
downloadaspectj-385356c6c19ff2e3f2899a6e4e80ceab5130cc03.tar.gz
aspectj-385356c6c19ff2e3f2899a6e4e80ceab5130cc03.zip
from branch: loads of @AJ changes for inlining strategies, using the right JP, wiring up the closure, etc.
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelShadow.java284
1 files changed, 234 insertions, 50 deletions
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
index 675286b16..17f766f28 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
@@ -1,13 +1,14 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * PARC initial implementation
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Alexandre Vasseur support for @AJ aspects
* ******************************************************************/
@@ -23,6 +24,7 @@ import java.util.Map;
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.generic.ACONST_NULL;
+import org.aspectj.apache.bcel.generic.ALOAD;
import org.aspectj.apache.bcel.generic.ANEWARRAY;
import org.aspectj.apache.bcel.generic.ArrayType;
import org.aspectj.apache.bcel.generic.BranchInstruction;
@@ -30,6 +32,7 @@ import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.apache.bcel.generic.DUP;
import org.aspectj.apache.bcel.generic.DUP_X1;
import org.aspectj.apache.bcel.generic.FieldInstruction;
+import org.aspectj.apache.bcel.generic.INVOKEINTERFACE;
import org.aspectj.apache.bcel.generic.INVOKESPECIAL;
import org.aspectj.apache.bcel.generic.INVOKESTATIC;
import org.aspectj.apache.bcel.generic.Instruction;
@@ -43,6 +46,7 @@ import org.aspectj.apache.bcel.generic.LoadInstruction;
import org.aspectj.apache.bcel.generic.MULTIANEWARRAY;
import org.aspectj.apache.bcel.generic.NEW;
import org.aspectj.apache.bcel.generic.ObjectType;
+import org.aspectj.apache.bcel.generic.POP;
import org.aspectj.apache.bcel.generic.PUSH;
import org.aspectj.apache.bcel.generic.ReturnInstruction;
import org.aspectj.apache.bcel.generic.SWAP;
@@ -70,6 +74,7 @@ import org.aspectj.weaver.TypeX;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.Var;
+import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
/*
@@ -1093,26 +1098,45 @@ public class BcelShadow extends Shadow {
return il;
}
-
+
+ /**
+ * Get the Var for the jpStaticPart
+ * @return
+ */
public BcelVar getThisJoinPointStaticPartBcelVar() {
+ return getThisJoinPointStaticPartBcelVar(false);
+ }
+
+ /**
+ * Get the Var for the xxxxJpStaticPart, xxx = this or enclosing
+ * @param isEnclosingJp true to have the enclosingJpStaticPart
+ * @return
+ */
+ public BcelVar getThisJoinPointStaticPartBcelVar(final boolean isEnclosingJp) {
if (thisJoinPointStaticPartVar == null) {
- Field field = getEnclosingClass().getTjpField(this);
+ Field field = getEnclosingClass().getTjpField(this, isEnclosingJp);
thisJoinPointStaticPartVar =
new BcelFieldRef(
- world.getCoreType(TypeX.forName("org.aspectj.lang.JoinPoint$StaticPart")),
+ isEnclosingJp?
+ world.getCoreType(TypeX.forName("org.aspectj.lang.JoinPoint$EnclosingStaticPart")):
+ world.getCoreType(TypeX.forName("org.aspectj.lang.JoinPoint$StaticPart")),
getEnclosingClass().getClassName(),
field.getName());
// getEnclosingClass().warnOnAddedStaticInitializer(this,munger.getSourceLocation());
}
return thisJoinPointStaticPartVar;
}
-
+
+ /**
+ * Get the Var for the enclosingJpStaticPart
+ * @return
+ */
public BcelVar getThisEnclosingJoinPointStaticPartBcelVar() {
if (enclosingShadow == null) {
// the enclosing of an execution is itself
- return getThisJoinPointStaticPartBcelVar();
+ return getThisJoinPointStaticPartBcelVar(true);
} else {
- return ((BcelShadow)enclosingShadow).getThisJoinPointStaticPartBcelVar();
+ return ((BcelShadow)enclosingShadow).getThisJoinPointStaticPartBcelVar(true);
}
}
@@ -1286,7 +1310,6 @@ public class BcelShadow extends Shadow {
thisAnnotationVars = new HashMap();
// populate..
}
-
public void initializeTargetAnnotationVars() {
if (targetAnnotationVars != null) return;
if (getKind().isTargetSameAsThis()) {
@@ -2024,9 +2047,9 @@ public class BcelShadow extends Shadow {
for (int i=extraParamOffset; i < nVars; i++) {
varMap.put(i-extraParamOffset, i);
}
-
+
localAdviceMethod.getBody().insert(
- BcelClassWeaver.genInlineInstructions(adviceMethod,
+ BcelClassWeaver.genInlineInstructions(adviceMethod,
localAdviceMethod, varMap, fact, true));
@@ -2054,7 +2077,9 @@ public class BcelShadow extends Shadow {
munger.getAdviceArgSetup(
this,
null,
- new InstructionList(InstructionConstants.ACONST_NULL)));
+ (munger.getConcreteAspect().isAnnotationStyleAspect())?
+ this.loadThisJoinPoint():
+ new InstructionList(InstructionConstants.ACONST_NULL)));
// adviceMethodInvocation =
advice.append(
Utility.createInvoke(fact, localAdviceMethod)); //(fact, getWorld(), munger.getSignature()));
@@ -2100,31 +2125,62 @@ public class BcelShadow extends Shadow {
// now search through the advice, looking for a call to PROCEED.
// Then we replace the call to proceed with some argument setup, and a
// call to the extracted method.
- String proceedName =
- NameMangler.proceedMethodName(munger.getSignature().getName());
-
- InstructionHandle curr = localAdviceMethod.getBody().getStart();
- InstructionHandle end = localAdviceMethod.getBody().getEnd();
- ConstantPoolGen cpg = localAdviceMethod.getEnclosingClass().getConstantPoolGen();
- while (curr != end) {
- InstructionHandle next = curr.getNext();
- Instruction inst = curr.getInstruction();
- if ((inst instanceof INVOKESTATIC)
- && proceedName.equals(((INVOKESTATIC) inst).getMethodName(cpg))) {
-
- localAdviceMethod.getBody().append(
- curr,
- getRedoneProceedCall(
- fact,
- extractedMethod,
- munger,
- localAdviceMethod,
- proceedVarList));
- Utility.deleteInstruction(curr, localAdviceMethod);
- }
- curr = next;
+
+ // inlining support for code style aspects
+ if (!munger.getConcreteAspect().isAnnotationStyleAspect()) {
+ String proceedName =
+ NameMangler.proceedMethodName(munger.getSignature().getName());
+
+ InstructionHandle curr = localAdviceMethod.getBody().getStart();
+ InstructionHandle end = localAdviceMethod.getBody().getEnd();
+ ConstantPoolGen cpg = localAdviceMethod.getEnclosingClass().getConstantPoolGen();
+ while (curr != end) {
+ InstructionHandle next = curr.getNext();
+ Instruction inst = curr.getInstruction();
+ if ((inst instanceof INVOKESTATIC)
+ && proceedName.equals(((INVOKESTATIC) inst).getMethodName(cpg))) {
+
+ localAdviceMethod.getBody().append(
+ curr,
+ getRedoneProceedCall(
+ fact,
+ extractedMethod,
+ munger,
+ localAdviceMethod,
+ proceedVarList));
+ Utility.deleteInstruction(curr, localAdviceMethod);
+ }
+ curr = next;
+ }
+ // and that's it.
+ } else {
+ //ATAJ inlining support for @AJ aspects
+ // [TODO document @AJ code rule: don't manipulate 2 jps proceed at the same time.. in an advice body]
+ InstructionHandle curr = localAdviceMethod.getBody().getStart();
+ InstructionHandle end = localAdviceMethod.getBody().getEnd();
+ ConstantPoolGen cpg = localAdviceMethod.getEnclosingClass().getConstantPoolGen();
+ while (curr != end) {
+ InstructionHandle next = curr.getNext();
+ Instruction inst = curr.getInstruction();
+ if ((inst instanceof INVOKEINTERFACE)
+ && "proceed".equals(((INVOKEINTERFACE) inst).getMethodName(cpg))) {
+ //TODO proceed(...varargs) will need some stuff there
+ InstructionList insteadProceedIl =
+ getRedoneProceedCallForAnnotationStyle(
+ fact,
+ extractedMethod,
+ munger,
+ localAdviceMethod,
+ proceedVarList);
+ //TODO optimize, a POP is added somewhere, what for non void ?
+ localAdviceMethod.getBody().append(
+ curr, insteadProceedIl);
+
+ Utility.deleteInstruction(curr, localAdviceMethod);
+ }
+ curr = next;
+ }
}
- // and that's it.
}
private InstructionList getRedoneProceedCall(
@@ -2153,11 +2209,10 @@ public class BcelShadow extends Shadow {
System.arraycopy(proceedParamTypes, 0, newTypes, 0, len);
proceedParamTypes = newTypes;
}
-
+
//System.out.println("stateTypes: " + Arrays.asList(stateTypes));
- BcelVar[] proceedVars =
+ BcelVar[] proceedVars =
Utility.pushAndReturnArrayOfVars(proceedParamTypes, ret, fact, localAdviceMethod);
-
Type[] stateTypes = callbackMethod.getArgumentTypes();
// System.out.println("stateTypes: " + Arrays.asList(stateTypes));
@@ -2177,8 +2232,117 @@ public class BcelShadow extends Shadow {
ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
return ret;
- }
-
+ }
+
+ /**
+ * ATAJ Handle the inlining for @AJ aspects
+ *
+ * @param fact
+ * @param callbackMethod
+ * @param munger
+ * @param localAdviceMethod
+ * @param argVarList
+ * @return
+ */
+ private InstructionList getRedoneProceedCallForAnnotationStyle(
+ InstructionFactory fact,
+ LazyMethodGen callbackMethod,
+ BcelAdvice munger,
+ LazyMethodGen localAdviceMethod,
+ List argVarList)
+ {
+ //if (true) return new InstructionList();
+
+ //TODO I think we just don't care about the proceed map
+ // since that one must be the exact same of the advice sig.
+ // perhaps with custom jp ?
+
+ // we have on stack all the arguments for the ADVICE call.
+ // we have in frame somewhere all the arguments for the non-advice call.
+ BcelVar[] adviceVars = munger.getExposedStateAsBcelVars();
+ IntMap proceedMap = makeProceedArgumentMap(adviceVars);
+
+ //System.out.println(proceedMap + " for " + this);
+ //System.out.println(argVarList);
+
+ ResolvedTypeX[] proceedParamTypes =
+ world.resolve(munger.getSignature().getParameterTypes());
+ //System.out.println(proceedParamTypes);
+
+ InstructionList ret = new InstructionList();
+ ret.append(new POP());//the joinpoint instance is there
+
+ for (int i=0, len=callbackMethod.getArgumentTypes().length; i < len; i++) {
+ Type stateType = callbackMethod.getArgumentTypes()[i];
+ ResolvedTypeX stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
+ if (proceedMap.hasKey(i)) {
+ ret.append(new ALOAD(i));
+ //throw new RuntimeException("unimplemented");
+ //proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
+ } else {
+ //FIXME Alex: odd code there
+ //((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
+ //ret.append(new ALOAD(i));
+ if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
+ ret.append(new ALOAD(i));
+ } else {
+ ret.append(new ALOAD(i));
+ }
+ }
+ }
+
+ ret.append(Utility.createInvoke(fact, callbackMethod));
+ ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
+ BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
+
+ ret.append(new ACONST_NULL());//will be POPed //FIXME Alex: if so clean up
+ if (true) return ret;
+
+
+
+// // we have on stack all the arguments for the ADVICE call.
+// // we have in frame somewhere all the arguments for the non-advice call.
+//
+// BcelVar[] adviceVars = munger.getExposedStateAsBcelVars();
+// IntMap proceedMap = makeProceedArgumentMap(adviceVars);
+//
+// System.out.println(proceedMap + " for " + this);
+// System.out.println(argVarList);
+//
+// ResolvedTypeX[] proceedParamTypes =
+// world.resolve(munger.getSignature().getParameterTypes());
+ // remove this*JoinPoint* as arguments to proceed
+ if (munger.getBaseParameterCount()+1 < proceedParamTypes.length) {
+ int len = munger.getBaseParameterCount()+1;
+ ResolvedTypeX[] newTypes = new ResolvedTypeX[len];
+ System.arraycopy(proceedParamTypes, 0, newTypes, 0, len);
+ proceedParamTypes = newTypes;
+ }
+
+ //System.out.println("stateTypes: " + Arrays.asList(stateTypes));
+ BcelVar[] proceedVars =
+ Utility.pushAndReturnArrayOfVars(proceedParamTypes, ret, fact, localAdviceMethod);
+
+ Type[] stateTypes = callbackMethod.getArgumentTypes();
+// System.out.println("stateTypes: " + Arrays.asList(stateTypes));
+
+ for (int i=0, len=stateTypes.length; i < len; i++) {
+ Type stateType = stateTypes[i];
+ ResolvedTypeX stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
+ if (proceedMap.hasKey(i)) {
+ //throw new RuntimeException("unimplemented");
+ proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
+ } else {
+ ((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
+ }
+ }
+
+ ret.append(Utility.createInvoke(fact, callbackMethod));
+ ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
+ BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
+ return ret;
+ }
+
public void weaveAroundClosure(
BcelAdvice munger,
boolean hasDynamicTest)
@@ -2269,12 +2433,32 @@ public class BcelShadow extends Shadow {
InstructionFactory.createReturn(callbackMethod.getReturnType()));
}
}
-
+
+ // ATAJ for @AJ aspect we need to link the closure with the joinpoint instance
+ if (Ajc5MemberMaker.isAnnotationStyleAspect(munger.getConcreteAspect())) {
+ //advice.append(new POP());
+ closureInstantiation.append(Utility.createInvoke(
+ getFactory(),
+ getWorld(),
+ new Member(
+ Member.METHOD,
+ TypeX.forName("org.aspectj.runtime.internal.AroundClosure"),
+ Modifier.PUBLIC,
+ "linkClosureAndJoinPoint",
+ "()Lorg/aspectj/lang/ProceedingJoinPoint;"
+ )
+ ));
+ }
+ //System.err.println(closureInstantiation);
+
+
InstructionList advice = new InstructionList();
advice.append(munger.getAdviceArgSetup(this, null, closureInstantiation));
// advice.append(closureInstantiation);
+
+ // invoke the advice
advice.append(munger.getNonTestAdviceInstructions(this));
- advice.append(returnConversionCode);
+ advice.append(returnConversionCode);
if (!hasDynamicTest) {
range.append(advice);
@@ -2398,7 +2582,7 @@ public class BcelShadow extends Shadow {
private LazyMethodGen makeClosureClassAndReturnConstructor(
String closureClassName,
LazyMethodGen callbackMethod,
- IntMap proceedMap)
+ IntMap proceedMap)
{
String superClassName = "org.aspectj.runtime.internal.AroundClosure";
Type objectArrayType = new ArrayType(Type.OBJECT, 1);