diff options
author | aclement <aclement> | 2006-01-20 09:40:54 +0000 |
---|---|---|
committer | aclement <aclement> | 2006-01-20 09:40:54 +0000 |
commit | 9c38e399f5d9c75fdd2b918752fba7fa12b28673 (patch) | |
tree | de3c39f2f1e99d4bf665a359a4db3a5c77f3d6a1 /weaver | |
parent | f51e0736ed52ca6bc3689981f53718b62471251a (diff) | |
download | aspectj-9c38e399f5d9c75fdd2b918752fba7fa12b28673.tar.gz aspectj-9c38e399f5d9c75fdd2b918752fba7fa12b28673.zip |
77166 - newarray joinpoint support. "-Xjoinpoints:arrayconstruction"
Diffstat (limited to 'weaver')
6 files changed, 130 insertions, 9 deletions
diff --git a/weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java b/weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java index b11f41f80..265f6f4e0 100644 --- a/weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java +++ b/weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java @@ -96,7 +96,17 @@ public class JoinPointSignatureIterator implements Iterator { // Walk up hierarchy creating one member for each type up to and including the // first defining type ResolvedType originalDeclaringType = signaturesOfMember.getDeclaringType().resolve(world); + + if (world.isJoinpointArrayConstructionEnabled() && originalDeclaringType.isArray()) { // Aha, this must be the array constructor call join point - a 'special'... + Member m = signaturesOfMember; + ResolvedMember rm = new ResolvedMemberImpl(m.getKind(),m.getDeclaringType(),m.getModifiers(),m.getReturnType(),m.getName(),m.getParameterTypes()); + discoveredSignatures.add(new JoinPointSignature(rm,originalDeclaringType)); + couldBeFurtherAsYetUndiscoveredSignatures = false; + return; + } + firstDefiningMember = (ResolvedMemberImpl) signaturesOfMember.resolve(world); + if (firstDefiningMember == null) { couldBeFurtherAsYetUndiscoveredSignatures = false; return; diff --git a/weaver/src/org/aspectj/weaver/Shadow.java b/weaver/src/org/aspectj/weaver/Shadow.java index 4d28fbe59..ab652b24c 100644 --- a/weaver/src/org/aspectj/weaver/Shadow.java +++ b/weaver/src/org/aspectj/weaver/Shadow.java @@ -142,7 +142,29 @@ public abstract class Shadow { return getSignature().getParameterTypes(); } + public boolean isShadowForArrayConstructionJoinpoint() { + return (getKind()==ConstructorCall && signature.getDeclaringType().isArray()); + } + + // will return the right length array of ints depending on how many dimensions the array has + public ResolvedType[] getArgumentTypesForArrayConstructionShadow() { + String s = signature.getDeclaringType().getSignature(); + int pos = s.indexOf("["); + int dims = 1; + while (pos<s.length()) { + pos++; + if (pos<s.length()) dims+=(s.charAt(pos)=='['?1:0); + } + if (dims==1) return new ResolvedType[]{ResolvedType.INT}; + ResolvedType[] someInts = new ResolvedType[dims]; + for (int i = 0; i < dims;i++) someInts[i] = ResolvedType.INT; + return someInts; + } + public UnresolvedType[] getGenericArgTypes() { + if (isShadowForArrayConstructionJoinpoint()) { + return getArgumentTypesForArrayConstructionShadow(); + } if (getKind() == FieldSet) return new UnresolvedType[] { getResolvedSignature().getGenericReturnType() }; return getResolvedSignature().getGenericParameterTypes(); } diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index a8193d2fa..c470a0ec6 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -665,6 +665,7 @@ public abstract class World implements Dump.INode { } public void setOptionalJoinpoints(String jps) { + if (jps==null) return; if (jps.indexOf("arrayconstruction")!=-1) { optionalJoinpoint_ArrayConstruction = true; } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index a2a887017..3e7f7a70d 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -29,6 +29,7 @@ import org.aspectj.apache.bcel.Constants; import org.aspectj.apache.bcel.classfile.Field; import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.apache.bcel.classfile.annotation.Annotation; +import org.aspectj.apache.bcel.generic.ANEWARRAY; import org.aspectj.apache.bcel.generic.BranchInstruction; import org.aspectj.apache.bcel.generic.CPInstruction; import org.aspectj.apache.bcel.generic.ConstantPoolGen; @@ -44,8 +45,10 @@ import org.aspectj.apache.bcel.generic.InstructionList; import org.aspectj.apache.bcel.generic.InstructionTargeter; import org.aspectj.apache.bcel.generic.InvokeInstruction; import org.aspectj.apache.bcel.generic.LocalVariableInstruction; +import org.aspectj.apache.bcel.generic.MULTIANEWARRAY; import org.aspectj.apache.bcel.generic.MethodGen; import org.aspectj.apache.bcel.generic.NEW; +import org.aspectj.apache.bcel.generic.NEWARRAY; import org.aspectj.apache.bcel.generic.ObjectType; import org.aspectj.apache.bcel.generic.PUTFIELD; import org.aspectj.apache.bcel.generic.PUTSTATIC; @@ -1881,7 +1884,40 @@ class BcelClassWeaver implements IClassWeaver { } else { matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator); } - } + } else if (world.isJoinpointArrayConstructionEnabled() && + (i instanceof NEWARRAY || i instanceof ANEWARRAY || i instanceof MULTIANEWARRAY)) { + if (canMatch(Shadow.ConstructorCall)) { + boolean debug = false; + if (debug) System.err.println("Found new array instruction: "+i); + if (i instanceof ANEWARRAY) { + ANEWARRAY arrayInstruction = (ANEWARRAY)i; + ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPoolGen()); + if (debug) System.err.println("Array type is "+arrayType); + BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); + match(ctorCallShadow,shadowAccumulator); + } else if (i instanceof NEWARRAY) { + NEWARRAY arrayInstruction = (NEWARRAY)i; + Type arrayType = arrayInstruction.getType(); + if (debug) System.err.println("Array type is "+arrayType); + BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); + match(ctorCallShadow,shadowAccumulator); + } else if (i instanceof MULTIANEWARRAY) { + MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY)i; + ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPoolGen()); + if (debug) System.err.println("Array type is "+arrayType); + BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); + match(ctorCallShadow,shadowAccumulator); + } + } +// see pr77166 if you are thinking about implementing this +// } else if (i instanceof AALOAD ) { +// AALOAD arrayLoad = (AALOAD)i; +// Type arrayType = arrayLoad.getType(clazz.getConstantPoolGen()); +// BcelShadow arrayLoadShadow = BcelShadow.makeArrayLoadCall(world,mg,ih,enclosingShadow); +// match(arrayLoadShadow,shadowAccumulator); +// } else if (i instanceof AASTORE) { +// // ... magic required + } // performance optimization... we only actually care about ASTORE instructions, // since that's what every javac type thing ever uses to start a handler, but for // now we'll do this for everybody. diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java index 3ff0d1764..6d04fcd00 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java @@ -269,7 +269,8 @@ public class BcelShadow extends Shadow { // this up, every ShadowRange would have three instructionHandle points, the start of // the arg-setup code, the start of the running code, and the end of the running code. if (getKind() == ConstructorCall) { - deleteNewAndDup(); + if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray()) + deleteNewAndDup(); // no new/dup for new array construction initializeArgVars(); } else if (getKind() == PreInitialization) { // pr74952 ShadowRange range = getRange(); @@ -377,12 +378,14 @@ public class BcelShadow extends Shadow { Range.InsideBefore); } if (getKind() == ConstructorCall) { - range.insert((Instruction) InstructionFactory.createDup(1), Range.InsideBefore); - range.insert( - fact.createNew( - (ObjectType) BcelWorld.makeBcelType( - getSignature().getDeclaringType())), - Range.InsideBefore); + if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray()) { + range.insert((Instruction) InstructionFactory.createDup(1), Range.InsideBefore); + range.insert( + fact.createNew( + (ObjectType) BcelWorld.makeBcelType( + getSignature().getDeclaringType())), + Range.InsideBefore); + } } } } @@ -781,7 +784,51 @@ public class BcelShadow extends Shadow { retargetAllBranches(callHandle, r.getStart()); return s; } + + public static BcelShadow makeArrayConstructorCall(BcelWorld world,LazyMethodGen enclosingMethod,InstructionHandle arrayInstruction,BcelShadow enclosingShadow) { + final InstructionList body = enclosingMethod.getBody(); + Member sig = world.makeJoinPointSignatureForArrayConstruction(enclosingMethod.getEnclosingClass(),arrayInstruction); + BcelShadow s = + new BcelShadow( + world, + ConstructorCall, + sig, + enclosingMethod, + enclosingShadow); + ShadowRange r = new ShadowRange(body); + r.associateWithShadow(s); + r.associateWithTargets( + Range.genStart(body, arrayInstruction), + Range.genEnd(body, arrayInstruction)); + retargetAllBranches(arrayInstruction, r.getStart()); + return s; + } + // see pr77166 +// public static BcelShadow makeArrayLoadCall( +// BcelWorld world, +// LazyMethodGen enclosingMethod, +// InstructionHandle arrayInstruction, +// BcelShadow enclosingShadow) +// { +// final InstructionList body = enclosingMethod.getBody(); +// Member sig = world.makeJoinPointSignatureForArrayLoad(enclosingMethod.getEnclosingClass(),arrayInstruction); +// BcelShadow s = +// new BcelShadow( +// world, +// MethodCall, +// sig, +// enclosingMethod, +// enclosingShadow); +// ShadowRange r = new ShadowRange(body); +// r.associateWithShadow(s); +// r.associateWithTargets( +// Range.genStart(body, arrayInstruction), +// Range.genEnd(body, arrayInstruction)); +// retargetAllBranches(arrayInstruction, r.getStart()); +// return s; +// } + public static BcelShadow makeMethodCall( BcelWorld world, LazyMethodGen enclosingMethod, diff --git a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java index ae4e507e5..04581891b 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java @@ -81,8 +81,13 @@ public class ArgsPointcut extends NameBindingPointcut { } private ResolvedType[] getArgumentsToMatchAgainst(Shadow shadow) { + + if (shadow.isShadowForArrayConstructionJoinpoint()) { + return shadow.getArgumentTypesForArrayConstructionShadow(); + } + ResolvedType[] argumentsToMatchAgainst = shadow.getIWorld().resolve(shadow.getGenericArgTypes()); - + // special treatment for adviceexecution which may have synthetic arguments we // want to ignore. if (shadow.getKind() == Shadow.AdviceExecution) { |