Browse Source

231396: Comment #4: Big Refactoring

tags/V1_6_1y
aclement 16 years ago
parent
commit
3259086920
34 changed files with 1068 additions and 1017 deletions
  1. 3
    0
      weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java
  2. 0
    2
      weaver/src/org/aspectj/weaver/AnnotationAJ.java
  3. 13
    13
      weaver/src/org/aspectj/weaver/AnnotationX.java
  4. 7
    7
      weaver/src/org/aspectj/weaver/FakeAnnotation.java
  5. 2
    2
      weaver/src/org/aspectj/weaver/JoinPointSignature.java
  6. 11
    32
      weaver/src/org/aspectj/weaver/Member.java
  7. 13
    10
      weaver/src/org/aspectj/weaver/MemberImpl.java
  8. 37
    0
      weaver/src/org/aspectj/weaver/MemberKind.java
  9. 1
    1
      weaver/src/org/aspectj/weaver/ResolvedMember.java
  10. 6
    6
      weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java
  11. 12
    4
      weaver/src/org/aspectj/weaver/SourceContextImpl.java
  12. 70
    79
      weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
  13. 15
    17
      weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java
  14. 55
    25
      weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java
  15. 2
    3
      weaver/src/org/aspectj/weaver/bcel/BcelCflowCounterFieldAdder.java
  16. 2
    3
      weaver/src/org/aspectj/weaver/bcel/BcelCflowStackFieldAdder.java
  17. 101
    113
      weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
  18. 65
    15
      weaver/src/org/aspectj/weaver/bcel/BcelField.java
  19. 95
    53
      weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
  20. 32
    22
      weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
  21. 28
    32
      weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java
  22. 46
    75
      weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
  23. 35
    34
      weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
  24. 1
    1
      weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
  25. 22
    32
      weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
  26. 160
    148
      weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
  27. 131
    193
      weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
  28. 2
    2
      weaver/src/org/aspectj/weaver/bcel/Range.java
  29. 12
    14
      weaver/src/org/aspectj/weaver/bcel/ShadowRange.java
  30. 76
    69
      weaver/src/org/aspectj/weaver/bcel/Utility.java
  31. 2
    1
      weaver/src/org/aspectj/weaver/patterns/PatternParser.java
  32. 5
    4
      weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
  33. 5
    4
      weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java
  34. 1
    1
      weaver/testsrc/org/aspectj/weaver/MemberTestCase.java

+ 3
- 0
weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java View File

@@ -258,6 +258,9 @@ public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDele
this.sourcefilename = pname.replace('.', '/') + '/' + sourceFileName;
}
}
if (this.sourcefilename!=null && sourceContext instanceof SourceContextImpl) {
((SourceContextImpl)sourceContext).setSourceFileName(this.sourcefilename);
}
}
public ISourceLocation getSourceLocation() {

+ 0
- 2
weaver/src/org/aspectj/weaver/AnnotationAJ.java View File

@@ -15,8 +15,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;

/**
* This type represents the weavers abstraction of an annotation - it is
* not tied to any underlying BCI toolkit. The weaver actualy handles these

+ 13
- 13
weaver/src/org/aspectj/weaver/AnnotationX.java View File

@@ -15,12 +15,12 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue;
import org.aspectj.apache.bcel.classfile.Utility;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;

/**
* AnnotationX instances are holders for an annotation from either Bcel or
@@ -31,8 +31,8 @@ public class AnnotationX {
public static final AnnotationX[] NONE = new AnnotationX[0];
private Annotation theRealBcelAnnotation;
private AnnotationAJ theRealEclipseAnnotation;
private AnnotationGen theRealBcelAnnotation;
private AnnotationAJ theRealEclipseAnnotation; // OPTIMIZE push out into compiler, not ever used if purely binary weaving ?
private int mode = -1;
private final static int MODE_ECLIPSE = 1;
private final static int MODE_BCEL = 2;
@@ -44,7 +44,7 @@ public class AnnotationX {
private AnnotationX atTargetAnnotation = null;
private Set supportedTargets = null;
public AnnotationX(Annotation a,World world) {
public AnnotationX(AnnotationGen a,World world) {
theRealBcelAnnotation = a;
signature = UnresolvedType.forSignature(theRealBcelAnnotation.getTypeSignature()).resolve(world);
mode = MODE_BCEL;
@@ -56,7 +56,7 @@ public class AnnotationX {
mode= MODE_ECLIPSE;
}

public Annotation getBcelAnnotation() {
public AnnotationGen getBcelAnnotation() {
return theRealBcelAnnotation;
}
@@ -168,11 +168,11 @@ public class AnnotationX {
Set supportedTargets = new HashSet();
if (mode==MODE_BCEL) {
List values = getBcelAnnotation().getValues();
ElementNameValuePair envp = (ElementNameValuePair)values.get(0);
ArrayElementValue aev = (ArrayElementValue)envp.getValue();
ElementValue[] evs = aev.getElementValuesArray();
ElementNameValuePairGen envp = (ElementNameValuePairGen)values.get(0);
ArrayElementValueGen aev = (ArrayElementValueGen)envp.getValue();
ElementValueGen[] evs = aev.getElementValuesArray();
for (int i = 0; i < evs.length; i++) {
EnumElementValue ev = (EnumElementValue)evs[i];
EnumElementValueGen ev = (EnumElementValueGen)evs[i];
supportedTargets.add(ev.getEnumValueString());
}
} else {

+ 7
- 7
weaver/src/org/aspectj/weaver/FakeAnnotation.java View File

@@ -15,8 +15,8 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;

import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;

/**
* For implementing declare @type interacting with declare @parents during compilation - we need to be
@@ -27,14 +27,14 @@ import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
* this will allow type resolution to succeed correctly. The FakeAnnotation never makes it to disk, since the weaver
* does the job properly, attaching a real annotation.
*/
public class FakeAnnotation extends Annotation {
public class FakeAnnotation extends AnnotationGen {

private String name;
private String sig;
private boolean isRuntimeVisible;
public FakeAnnotation(String name,String sig,boolean isRuntimeVisible) {
super(0,null,true);
super(null,null,true,null);
this.name = name;
this.sig = sig;
this.isRuntimeVisible = isRuntimeVisible;
@@ -48,11 +48,11 @@ public class FakeAnnotation extends Annotation {
return sig;
}

public void addElementNameValuePair(ElementNameValuePair evp) {
public void addElementNameValuePair(ElementNameValuePairGen evp) {
// doesnt need to know about name/value pairs
}

protected void dump(DataOutputStream dos) throws IOException {
public void dump(DataOutputStream dos) throws IOException {
// should be serialized
}

@@ -68,7 +68,7 @@ public class FakeAnnotation extends Annotation {
return isRuntimeVisible;
}

protected void isRuntimeVisible(boolean b) {
protected void setIsRuntimeVisible(boolean b) {
}

public String toShortString() {

+ 2
- 2
weaver/src/org/aspectj/weaver/JoinPointSignature.java View File

@@ -248,7 +248,7 @@ public class JoinPointSignature implements ResolvedMember {
return realMember.toLongString();
}

public Kind getKind() {
public MemberKind getKind() {
return realMember.getKind();
}

@@ -386,7 +386,7 @@ public class JoinPointSignature implements ResolvedMember {
realMember.resetName(newName);
}

public void resetKind(Kind newKind) {
public void resetKind(MemberKind newKind) {
realMember.resetKind(newKind);
}

+ 11
- 32
weaver/src/org/aspectj/weaver/Member.java View File

@@ -18,52 +18,31 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;

import org.aspectj.util.TypeSafeEnum;

public interface Member {

public static class Kind extends TypeSafeEnum {
public Kind(String name, int key) { super(name, key); }
public static Kind read(DataInputStream s) throws IOException {
int key = s.readByte();
switch(key) {
case 1: return METHOD;
case 2: return FIELD;
case 3: return CONSTRUCTOR;
case 4: return STATIC_INITIALIZATION;
case 5: return POINTCUT;
case 6: return ADVICE;
case 7: return HANDLER;
case 8: return MONITORENTER;
case 9: return MONITOREXIT;
}
throw new BCException("weird kind " + key);
}
}

public static final Member[] NONE = new Member[0];
public static final Kind METHOD = new Kind("METHOD", 1);
public static final Kind FIELD = new Kind("FIELD", 2);
public static final Kind CONSTRUCTOR = new Kind("CONSTRUCTOR", 3);
public static final Kind STATIC_INITIALIZATION = new Kind("STATIC_INITIALIZATION", 4);
public static final Kind POINTCUT = new Kind("POINTCUT", 5);
public static final Kind ADVICE = new Kind("ADVICE", 6);
public static final Kind HANDLER = new Kind("HANDLER", 7);
public static final Kind MONITORENTER = new Kind("MONITORENTER", 8);
public static final Kind MONITOREXIT = new Kind("MONITOREXIT", 9);
public static final MemberKind METHOD = new MemberKind("METHOD", 1);
public static final MemberKind FIELD = new MemberKind("FIELD", 2);
public static final MemberKind CONSTRUCTOR = new MemberKind("CONSTRUCTOR", 3);
public static final MemberKind STATIC_INITIALIZATION = new MemberKind("STATIC_INITIALIZATION", 4);
public static final MemberKind POINTCUT = new MemberKind("POINTCUT", 5);
public static final MemberKind ADVICE = new MemberKind("ADVICE", 6);
public static final MemberKind HANDLER = new MemberKind("HANDLER", 7);
public static final MemberKind MONITORENTER = new MemberKind("MONITORENTER", 8);
public static final MemberKind MONITOREXIT = new MemberKind("MONITOREXIT", 9);

public static final AnnotationX[][] NO_PARAMETER_ANNOTATIONXS = new AnnotationX[][]{};
public static final ResolvedType[][] NO_PARAMETER_ANNOTATION_TYPES = new ResolvedType[][]{};
public MemberKind getKind();
public ResolvedMember resolve(World world);

public int compareTo(Object other);

public String toLongString();

public Kind getKind();

public UnresolvedType getDeclaringType();

public UnresolvedType getReturnType();

+ 13
- 10
weaver/src/org/aspectj/weaver/MemberImpl.java View File

@@ -23,14 +23,16 @@ import java.util.List;

public class MemberImpl implements Comparable, AnnotatedElement,Member {
protected Kind kind;
protected MemberKind kind;
protected String name;
protected UnresolvedType declaringType;
protected int modifiers;
protected UnresolvedType returnType;
protected String name;
protected UnresolvedType[] parameterTypes;
private final String signature;
private String paramSignature;
// OPTIMIZE move out of the member!
private boolean reportedCantFindDeclaringType = false;
private boolean reportedUnresolvableMember = false;

@@ -43,7 +45,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
private JoinPointSignatureIterator joinPointSignatures = null;

public MemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
String name,
@@ -68,7 +70,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
}

public MemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
UnresolvedType returnType,
@@ -433,7 +435,6 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
return buf.toString();
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#toLongString()
*/
@@ -455,7 +456,9 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getKind()
*/
public Kind getKind() { return kind; }
public MemberKind getKind() {
return kind;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getDeclaringType()
*/
@@ -712,7 +715,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
public String getSignatureMakerName() {
if (getName().equals("<clinit>")) return "makeInitializerSig";
Kind kind = getKind();
MemberKind kind = getKind();
if (kind == METHOD) {
return "makeMethodSig";
} else if (kind == CONSTRUCTOR) {
@@ -741,7 +744,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
* @see org.aspectj.weaver.Member#getSignatureType()
*/
public String getSignatureType() {
Kind kind = getKind();
MemberKind kind = getKind();
if (getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature";
if (kind == METHOD) {
@@ -771,7 +774,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
public String getSignatureString(World world) {
if (getName().equals("<clinit>")) return getStaticInitializationSignatureString(world);
Kind kind = getKind();
MemberKind kind = getKind();
if (kind == METHOD) {
return getMethodSignatureString(world);
} else if (kind == CONSTRUCTOR) {
@@ -911,7 +914,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
}

protected String makeString(int i) {
return Integer.toString(i, 16); //??? expensive
return Integer.toString(i, 16);
}



+ 37
- 0
weaver/src/org/aspectj/weaver/MemberKind.java View File

@@ -0,0 +1,37 @@
/* *******************************************************************
* 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 Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* ******************************************************************/
package org.aspectj.weaver;

import java.io.DataInputStream;
import java.io.IOException;

import org.aspectj.util.TypeSafeEnum;

public class MemberKind extends TypeSafeEnum {
public MemberKind(String name, int key) { super(name, key); }
public static MemberKind read(DataInputStream s) throws IOException {
int key = s.readByte();
switch(key) {
case 1: return Member.METHOD;
case 2: return Member.FIELD;
case 3: return Member.CONSTRUCTOR;
case 4: return Member.STATIC_INITIALIZATION;
case 5: return Member.POINTCUT;
case 6: return Member.ADVICE;
case 7: return Member.HANDLER;
case 8: return Member.MONITORENTER;
case 9: return Member.MONITOREXIT;
}
throw new BCException("weird kind " + key);
}
}

+ 1
- 1
weaver/src/org/aspectj/weaver/ResolvedMember.java View File

@@ -155,7 +155,7 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
public boolean matches(ResolvedMember aCandidateMatch);
public void resetName(String newName);
public void resetKind(Kind newKind);
public void resetKind(MemberKind newKind);
public void resetModifiers(int newModifiers);
public void resetReturnTypeToObjectArray();

+ 6
- 6
weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java View File

@@ -60,7 +60,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
//XXX deprecate this in favor of the constructor below
public ResolvedMemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
UnresolvedType returnType,
@@ -73,7 +73,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
public ResolvedMemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
UnresolvedType returnType,
@@ -86,7 +86,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
public ResolvedMemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
UnresolvedType returnType,
@@ -101,7 +101,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
public ResolvedMemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
String name,
@@ -413,7 +413,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
public static ResolvedMemberImpl readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext) throws IOException {
ResolvedMemberImpl m = new ResolvedMemberImpl(Kind.read(s), UnresolvedType.read(s), s.readInt(),
ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), UnresolvedType.read(s), s.readInt(),
s.readUTF(), s.readUTF());
m.checkedExceptions = UnresolvedType.readArray(s);
@@ -838,7 +838,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
* using this method - this is safe.
*/
public void resetName(String newName) {this.name = newName;}
public void resetKind(Kind newKind) {this.kind=newKind; }
public void resetKind(MemberKind newKind) { this.kind = newKind; }
public void resetModifiers(int newModifiers) {this.modifiers=newModifiers;}

public void resetReturnTypeToObjectArray() {

+ 12
- 4
weaver/src/org/aspectj/weaver/SourceContextImpl.java View File

@@ -21,20 +21,28 @@ import org.aspectj.bridge.SourceLocation;

public class SourceContextImpl implements ISourceContext {
private AbstractReferenceTypeDelegate delegate;
// private AbstractReferenceTypeDelegate delegate;
private int[] lineBreaks;
String sfname;
public SourceContextImpl(AbstractReferenceTypeDelegate delegate) {
this.delegate = delegate;
// this.delegate = delegate;
sfname = delegate.getSourcefilename();
}
public void configureFromAttribute(String name,int []linebreaks) {
this.delegate.setSourcefilename(name);
// this.delegate.setSourcefilename(name);
sfname = name;
this.lineBreaks = linebreaks;
}
public void setSourceFileName(String name) {
sfname = name;
}
private File getSourceFile() {
return new File(delegate.getSourcefilename());
return new File(sfname);
// return new File(delegate.getSourcefilename());
}
public void tidy() {}

+ 70
- 79
weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java View File

@@ -28,9 +28,9 @@ import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.LocalVariable;
import org.aspectj.apache.bcel.classfile.LocalVariableTable;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ClassElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
import org.aspectj.apache.bcel.generic.Type;
@@ -75,9 +75,7 @@ import org.aspectj.weaver.patterns.SimpleScope;
import org.aspectj.weaver.patterns.TypePattern;

/**
* Annotation defined aspect reader.
* <p/>
* It reads the Java 5 annotations and turns them into AjAttributes
* Annotation defined aspect reader. Reads the Java 5 annotations and turns them into AjAttributes
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
@@ -94,8 +92,6 @@ public class AtAjAttributes {

/**
* A struct that allows to add extra arguments without always breaking the API
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
private static class AjAttributeStruct {

@@ -149,8 +145,6 @@ public class AtAjAttributes {

/**
* A struct when we read @AJ on field
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
private static class AjAttributeFieldStruct extends AjAttributeStruct {

@@ -184,42 +178,38 @@ public class AtAjAttributes {
* @return list of AjAttributes
*/
public static List readAj5ClassAttributes(JavaClass javaClass, ReferenceType type, ISourceContext context, IMessageHandler msgHandler, boolean isCodeStyleAspect) {
boolean containsPointcut = false;
//FIXME AV - 1.5 feature limitation, kick after implemented
boolean ignoreThisClass = javaClass.getClassName().charAt(0)=='o' && javaClass.getClassName().startsWith("org.aspectj.lang.annotation");
if (ignoreThisClass) return EMPTY_LIST;
try {
boolean containsAnnotationClassReference = false;
Constant[] cpool = javaClass.getConstantPool().getConstantPool();
for (int i = 0; i < cpool.length; i++) {
Constant constant = cpool[i];
if (constant != null && constant.getTag() == Constants.CONSTANT_Utf8) {
String constantValue = ((ConstantUtf8)constant).getBytes();
if (constantValue.length()>28 && constantValue.charAt(1)=='o') {
if (constantValue.startsWith("Lorg/aspectj/lang/annotation")) {
containsAnnotationClassReference=true;
if ("Lorg/aspectj/lang/annotation/DeclareAnnotation;".equals(constantValue)) {
msgHandler.handleMessage(
new Message(
"Found @DeclareAnnotation while current release does not support it (see '" + type.getName() + "')",
IMessage.WARNING,
null,
type.getSourceLocation()
)
);
}
if ("Lorg/aspectj/lang/annotation/Pointcut;".equals(constantValue)) {
containsPointcut=true;
}
}
}
boolean containsPointcut = false;
boolean containsAnnotationClassReference = false;
Constant[] cpool = javaClass.getConstantPool().getConstantPool();
for (int i = 0; i < cpool.length; i++) {
Constant constant = cpool[i];
if (constant != null && constant.getTag() == Constants.CONSTANT_Utf8) {
String constantValue = ((ConstantUtf8)constant).getBytes();
if (constantValue.length()>28 && constantValue.charAt(1)=='o') {
if (constantValue.startsWith("Lorg/aspectj/lang/annotation")) {
containsAnnotationClassReference=true;
if ("Lorg/aspectj/lang/annotation/DeclareAnnotation;".equals(constantValue)) {
msgHandler.handleMessage(
new Message(
"Found @DeclareAnnotation while current release does not support it (see '" + type.getName() + "')",
IMessage.WARNING,
null,
type.getSourceLocation()
)
);
}
if ("Lorg/aspectj/lang/annotation/Pointcut;".equals(constantValue)) {
containsPointcut=true;
}
}
}
}
if (!containsAnnotationClassReference) return EMPTY_LIST;
} catch (Throwable t) {
;
}

if (!containsAnnotationClassReference) return EMPTY_LIST;

AjAttributeStruct struct = new AjAttributeStruct(type, context, msgHandler);
Attribute[] attributes = javaClass.getAttributes();
@@ -230,7 +220,7 @@ public class AtAjAttributes {
Attribute attribute = attributes[i];
if (acceptAttribute(attribute)) {
RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
// we don't need to look for several attribute occurence since it cannot happen as per JSR175
// we don't need to look for several attribute occurrences since it cannot happen as per JSR175
if (!isCodeStyleAspect && !javaClass.isInterface()) {
hasAtAspectAnnotation = handleAspectAnnotation(rvs, struct);
//TODO AV - if put outside the if isCodeStyleAspect then we would enable mix style
@@ -318,8 +308,9 @@ public class AtAjAttributes {


// code style declare error / warning / implements / parents are field attributes
for (int i = 0; i < javaClass.getFields().length; i++) {
Field field = javaClass.getFields()[i];
Field[] fs = javaClass.getFields();
for (int i = 0; i < fs.length; i++) {
Field field = fs[i];
if (field.getName().startsWith(NameMangler.PREFIX)) continue; // already dealt with by ajc...
//FIXME alex optimize, this method struct will gets recreated for advice extraction
AjAttributeFieldStruct fstruct = new AjAttributeFieldStruct(field, null, type, context, msgHandler);
@@ -499,7 +490,7 @@ public class AtAjAttributes {
* @return true if found
*/
private static boolean handleAspectAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeStruct struct) {
Annotation aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.ASPECT_ANNOTATION);
AnnotationGen aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.ASPECT_ANNOTATION);
if (aspect != null) {
// semantic check for inheritance (only one level up)
boolean extendsAspect = false;
@@ -511,7 +502,7 @@ public class AtAjAttributes {
extendsAspect = struct.enclosingType.getSuperclass().isAspect();
}

ElementNameValuePair aspectPerClause = getAnnotationElement(aspect, VALUE);
ElementNameValuePairGen aspectPerClause = getAnnotationElement(aspect, VALUE);
final PerClause perClause;
if (aspectPerClause == null) {
// empty value means singleton unless inherited
@@ -619,9 +610,9 @@ public class AtAjAttributes {
* @return true if found
*/
private static boolean handlePrecedenceAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeStruct struct) {
Annotation aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPRECEDENCE_ANNOTATION);
AnnotationGen aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPRECEDENCE_ANNOTATION);
if (aspect != null) {
ElementNameValuePair precedence = getAnnotationElement(aspect, VALUE);
ElementNameValuePairGen precedence = getAnnotationElement(aspect, VALUE);
if (precedence != null) {
String precedencePattern = precedence.getValue().stringifyValue();
PatternParser parser = new PatternParser(precedencePattern);
@@ -643,7 +634,7 @@ public class AtAjAttributes {
// private static boolean handleDeclareImplementsAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {//, ResolvedPointcutDefinition preResolvedPointcut) {
// Annotation deci = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREIMPLEMENTS_ANNOTATION);
// if (deci != null) {
// ElementNameValuePair deciPatternNVP = getAnnotationElement(deci, VALUE);
// ElementNameValuePairGen deciPatternNVP = getAnnotationElement(deci, VALUE);
// String deciPattern = deciPatternNVP.getValue().stringifyValue();
// if (deciPattern != null) {
// TypePattern typePattern = parseTypePattern(deciPattern, struct);
@@ -683,9 +674,9 @@ public class AtAjAttributes {
* @return true if found
*/
private static boolean handleDeclareParentsAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {//, ResolvedPointcutDefinition preResolvedPointcut) {
Annotation decp = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPARENTS_ANNOTATION);
AnnotationGen decp = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPARENTS_ANNOTATION);
if (decp != null) {
ElementNameValuePair decpPatternNVP = getAnnotationElement(decp, VALUE);
ElementNameValuePairGen decpPatternNVP = getAnnotationElement(decp, VALUE);
String decpPattern = decpPatternNVP.getValue().stringifyValue();
if (decpPattern != null) {
TypePattern typePattern = parseTypePattern(decpPattern, struct);
@@ -710,9 +701,9 @@ public class AtAjAttributes {

// do we have a defaultImpl=xxx.class (ie implementation)
String defaultImplClassName = null;
ElementNameValuePair defaultImplNVP = getAnnotationElement(decp, "defaultImpl");
ElementNameValuePairGen defaultImplNVP = getAnnotationElement(decp, "defaultImpl");
if (defaultImplNVP != null) {
ClassElementValue defaultImpl = (ClassElementValue) defaultImplNVP.getValue();
ClassElementValueGen defaultImpl = (ClassElementValueGen) defaultImplNVP.getValue();
defaultImplClassName = UnresolvedType.forSignature(defaultImpl.getClassString()).getName();
if (defaultImplClassName.equals("org.aspectj.lang.annotation.DeclareParents")) {
defaultImplClassName = null;
@@ -809,9 +800,9 @@ public class AtAjAttributes {
* @return true if found
*/
private static boolean handleBeforeAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
Annotation before = getAnnotation(runtimeAnnotations, AjcMemberMaker.BEFORE_ANNOTATION);
AnnotationGen before = getAnnotation(runtimeAnnotations, AjcMemberMaker.BEFORE_ANNOTATION);
if (before != null) {
ElementNameValuePair beforeAdvice = getAnnotationElement(before, VALUE);
ElementNameValuePairGen beforeAdvice = getAnnotationElement(before, VALUE);
if (beforeAdvice != null) {
// this/target/args binding
String argumentNames = getArgNamesValue(before);
@@ -869,9 +860,9 @@ public class AtAjAttributes {
* @return true if found
*/
private static boolean handleAfterAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTER_ANNOTATION);
AnnotationGen after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTER_ANNOTATION);
if (after != null) {
ElementNameValuePair afterAdvice = getAnnotationElement(after, VALUE);
ElementNameValuePairGen afterAdvice = getAnnotationElement(after, VALUE);
if (afterAdvice != null) {
// this/target/args binding
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
@@ -934,11 +925,11 @@ public class AtAjAttributes {
BcelMethod owningMethod)
throws ReturningFormalNotDeclaredInAdviceSignatureException
{
Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERRETURNING_ANNOTATION);
AnnotationGen after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERRETURNING_ANNOTATION);
if (after != null) {
ElementNameValuePair annValue = getAnnotationElement(after, VALUE);
ElementNameValuePair annPointcut = getAnnotationElement(after, POINTCUT);
ElementNameValuePair annReturned = getAnnotationElement(after, RETURNING);
ElementNameValuePairGen annValue = getAnnotationElement(after, VALUE);
ElementNameValuePairGen annPointcut = getAnnotationElement(after, POINTCUT);
ElementNameValuePairGen annReturned = getAnnotationElement(after, RETURNING);

// extract the pointcut and returned type/binding - do some checks
String pointcut = null;
@@ -1034,11 +1025,11 @@ public class AtAjAttributes {
BcelMethod owningMethod)
throws ThrownFormalNotDeclaredInAdviceSignatureException
{
Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERTHROWING_ANNOTATION);
AnnotationGen after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERTHROWING_ANNOTATION);
if (after != null) {
ElementNameValuePair annValue = getAnnotationElement(after, VALUE);
ElementNameValuePair annPointcut = getAnnotationElement(after, POINTCUT);
ElementNameValuePair annThrown = getAnnotationElement(after, THROWING);
ElementNameValuePairGen annValue = getAnnotationElement(after, VALUE);
ElementNameValuePairGen annPointcut = getAnnotationElement(after, POINTCUT);
ElementNameValuePairGen annThrown = getAnnotationElement(after, THROWING);

// extract the pointcut and throwned type/binding - do some checks
String pointcut = null;
@@ -1128,9 +1119,9 @@ public class AtAjAttributes {
* @return true if found
*/
private static boolean handleAroundAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) {
Annotation around = getAnnotation(runtimeAnnotations, AjcMemberMaker.AROUND_ANNOTATION);
AnnotationGen around = getAnnotation(runtimeAnnotations, AjcMemberMaker.AROUND_ANNOTATION);
if (around != null) {
ElementNameValuePair aroundAdvice = getAnnotationElement(around, VALUE);
ElementNameValuePairGen aroundAdvice = getAnnotationElement(around, VALUE);
if (aroundAdvice != null) {
// this/target/args binding
String argumentNames = getArgNamesValue(around);
@@ -1187,9 +1178,9 @@ public class AtAjAttributes {
* @return true if a pointcut was handled
*/
private static boolean handlePointcutAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
Annotation pointcut = getAnnotation(runtimeAnnotations, AjcMemberMaker.POINTCUT_ANNOTATION);
AnnotationGen pointcut = getAnnotation(runtimeAnnotations, AjcMemberMaker.POINTCUT_ANNOTATION);
if (pointcut==null) return false;
ElementNameValuePair pointcutExpr = getAnnotationElement(pointcut, VALUE);
ElementNameValuePairGen pointcutExpr = getAnnotationElement(pointcut, VALUE);

// semantic check: the method must return void, or be "public static boolean" for if() support
@@ -1281,10 +1272,10 @@ public class AtAjAttributes {
* @return true if found
*/
private static boolean handleDeclareErrorOrWarningAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {
Annotation error = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREERROR_ANNOTATION);
AnnotationGen error = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREERROR_ANNOTATION);
boolean hasError = false;
if (error != null) {
ElementNameValuePair declareError = getAnnotationElement(error, VALUE);
ElementNameValuePairGen declareError = getAnnotationElement(error, VALUE);
if (declareError != null) {
if (!STRING_DESC.equals(struct.field.getSignature()) || struct.field.getConstantValue() == null) {
reportError("@DeclareError used on a non String constant field", struct);
@@ -1301,10 +1292,10 @@ public class AtAjAttributes {
}
}
}
Annotation warning = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREWARNING_ANNOTATION);
AnnotationGen warning = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREWARNING_ANNOTATION);
boolean hasWarning = false;
if (warning != null) {
ElementNameValuePair declareWarning = getAnnotationElement(warning, VALUE);
ElementNameValuePairGen declareWarning = getAnnotationElement(warning, VALUE);
if (declareWarning != null) {
if (!STRING_DESC.equals(struct.field.getSignature()) || struct.field.getConstantValue() == null) {
reportError("@DeclareWarning used on a non String constant field", struct);
@@ -1504,10 +1495,10 @@ public class AtAjAttributes {
* @param annotationType
* @return annotation
*/
private static Annotation getAnnotation(RuntimeAnnotations rvs, UnresolvedType annotationType) {
private static AnnotationGen getAnnotation(RuntimeAnnotations rvs, UnresolvedType annotationType) {
final String annotationTypeName = annotationType.getName();
for (Iterator iterator = rvs.getAnnotations().iterator(); iterator.hasNext();) {
Annotation rv = (Annotation) iterator.next();
AnnotationGen rv = (AnnotationGen) iterator.next();
if (annotationTypeName.equals(rv.getTypeName())) {
return rv;
}
@@ -1523,9 +1514,9 @@ public class AtAjAttributes {
* @param elementName
* @return annotation NVP
*/
private static ElementNameValuePair getAnnotationElement(Annotation annotation, String elementName) {
private static ElementNameValuePairGen getAnnotationElement(AnnotationGen annotation, String elementName) {
for (Iterator iterator1 = annotation.getValues().iterator(); iterator1.hasNext();) {
ElementNameValuePair element = (ElementNameValuePair) iterator1.next();
ElementNameValuePairGen element = (ElementNameValuePairGen) iterator1.next();
if (elementName.equals(element.getNameString())) {
return element;
}
@@ -1536,9 +1527,9 @@ public class AtAjAttributes {
/**
* Return the argNames set for an annotation or null if it is not specified.
*/
private static String getArgNamesValue(Annotation anno) {
private static String getArgNamesValue(AnnotationGen anno) {
for (Iterator iterator1 = anno.getValues().iterator(); iterator1.hasNext();) {
ElementNameValuePair element = (ElementNameValuePair) iterator1.next();
ElementNameValuePairGen element = (ElementNameValuePairGen) iterator1.next();
if (ARGNAMES.equals(element.getNameString())) {
return element.getValue().stringifyValue();
}

+ 15
- 17
weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java View File

@@ -12,10 +12,8 @@
package org.aspectj.weaver.bcel;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.generic.FieldInstruction;
import org.aspectj.apache.bcel.generic.GETFIELD;
import org.aspectj.apache.bcel.generic.GETSTATIC;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
@@ -133,7 +131,7 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
private void openAroundAdvice(LazyMethodGen aroundAdvice) {
InstructionHandle curr = aroundAdvice.getBody().getStart();
InstructionHandle end = aroundAdvice.getBody().getEnd();
ConstantPoolGen cpg = aroundAdvice.getEnclosingClass().getConstantPoolGen();
ConstantPool cpg = aroundAdvice.getEnclosingClass().getConstantPool();
InstructionFactory factory = aroundAdvice.getEnclosingClass().getFactory();

boolean realizedCannotInline = false;
@@ -205,7 +203,7 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
&& invoke.getSignature(cpg).equals(resolvedMember.getSignature())
&& !resolvedMember.isPublic()) {
final ResolvedMember accessor;
if ((inst instanceof GETFIELD) || (inst instanceof GETSTATIC)) {
if ((inst.opcode==Constants.GETFIELD) || (inst.opcode==Constants.GETSTATIC)) {
accessor = createOrGetInlineAccessorForFieldGet(resolvedMember);
} else {
accessor = createOrGetInlineAccessorForFieldSet(resolvedMember);
@@ -259,13 +257,13 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
// flag it synthetic, AjSynthetic
method.makeSynthetic();
method.addAttribute(
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPoolGen())
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(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false),
m_aspectGen.getConstantPoolGen()
m_aspectGen.getConstantPool()
)
);

@@ -320,13 +318,13 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
// flag it synthetic, AjSynthetic
method.makeSynthetic();
method.addAttribute(
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPoolGen())
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(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false),
m_aspectGen.getConstantPoolGen()
m_aspectGen.getConstantPool()
)
);

@@ -382,13 +380,13 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
// flag it synthetic, AjSynthetic
method.makeSynthetic();
method.addAttribute(
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPoolGen())
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(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet, false),
m_aspectGen.getConstantPoolGen()
m_aspectGen.getConstantPool()
)
);

@@ -440,13 +438,13 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
// flag it synthetic, AjSynthetic
method.makeSynthetic();
method.addAttribute(
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPoolGen())
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(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet, false),
m_aspectGen.getConstantPoolGen()
m_aspectGen.getConstantPool()
)
);


+ 55
- 25
weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java View File

@@ -18,7 +18,6 @@ import java.util.List;

import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.Unknown;
import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
@@ -28,16 +27,50 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;

// this is a class o' static methods for reading attributes. It's pretty much a bridge from
// bcel to AjAttribute.
// OPTIMIZE move the contents of this class to bcel Utility
class BcelAttributes {

/**
* Process an array of Bcel attributes - looking for those with the name prefix org.aspectj.weaver. The returned
* list contains the AspectJ attributes identified and unpacked to 'AjAttribute' objects.
*/
public static List readAjAttributes(String classname,Attribute[] as, ISourceContext context,
World w,AjAttribute.WeaverVersionInfo version) {
// public static List readAjAttributes(String classname,List as, ISourceContext context,
// World w, AjAttribute.WeaverVersionInfo version) {
// List l = new ArrayList();
//
// // first pass, look for version
// List forSecondPass = new ArrayList();
// for (int i = as.size() - 1; i >= 0; i--) {
// Attribute a = (Attribute)as.get(i);
// if (a instanceof Unknown) {
// Unknown u = (Unknown) a;
// String name = u.getName();
// if (name.charAt(0)=='o') { // 'o'rg.aspectj
// if (name.startsWith(AjAttribute.AttributePrefix)) {
// if (name.endsWith(WeaverVersionInfo.AttributeName)) {
// version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,w);
// if (version.getMajorVersion() > WeaverVersionInfo.getCurrentWeaverMajorVersion()) {
// throw new BCException("Unable to continue, this version of AspectJ supports classes built with weaver version "+
// WeaverVersionInfo.toCurrentVersionString()+" but the class "+classname+" is version "+version.toString());
// }
// }
// forSecondPass.add(a);
// }
// }
// }
// }
// for (int i = forSecondPass.size()-1; i >= 0; i--) {
// Unknown a = (Unknown)forSecondPass.get(i);
// String name = a.getName();
// AjAttribute attr = AjAttribute.read(version,name,a.getBytes(),context,w);
// if (attr!=null) l.add(attr);
// }
// return l;
// }
public static List readAjAttributes(String classname, Attribute[] as, ISourceContext context, World w, AjAttribute.WeaverVersionInfo version) {
List l = new ArrayList();
// first pass, look for version
List forSecondPass = new ArrayList();
for (int i = as.length - 1; i >= 0; i--) {
@@ -45,37 +78,34 @@ class BcelAttributes {
if (a instanceof Unknown) {
Unknown u = (Unknown) a;
String name = u.getName();
if (name.charAt(0)=='o') { // 'o'rg.aspectj
if (name.charAt(0) == 'o') { // 'o'rg.aspectj
if (name.startsWith(AjAttribute.AttributePrefix)) {
if (name.endsWith(WeaverVersionInfo.AttributeName)) {
version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,w);
if (version.getMajorVersion() > WeaverVersionInfo.getCurrentWeaverMajorVersion()) {
throw new BCException("Unable to continue, this version of AspectJ supports classes built with weaver version "+
WeaverVersionInfo.toCurrentVersionString()+" but the class "+classname+" is version "+version.toString());
version = (AjAttribute.WeaverVersionInfo) AjAttribute.read(version, name, u.getBytes(), context, w);
if (version.getMajorVersion() > WeaverVersionInfo
.getCurrentWeaverMajorVersion()) {
throw new BCException(
"Unable to continue, this version of AspectJ supports classes built with weaver version "
+ WeaverVersionInfo
.toCurrentVersionString()
+ " but the class "
+ classname
+ " is version "
+ version.toString());
}
}
}
forSecondPass.add(a);
}
}
}
}
for (int i = forSecondPass.size()-1; i >= 0; i--) {
Unknown a = (Unknown)forSecondPass.get(i);
for (int i = forSecondPass.size() - 1; i >= 0; i--) {
Unknown a = (Unknown) forSecondPass.get(i);
String name = a.getName();
AjAttribute attr = AjAttribute.read(version,name,a.getBytes(),context,w);
if (attr!=null) l.add(attr);
AjAttribute attr = AjAttribute.read(version, name, a.getBytes(), context, w);
if (attr != null) l.add(attr);
}
return l;
}

public static Attribute bcelAttribute(AjAttribute a, ConstantPoolGen pool) {
int nameIndex = pool.addUtf8(a.getNameString());
byte[] bytes = a.getBytes();
int length = bytes.length;

return new Unknown(nameIndex, length, bytes, pool.getConstantPool());

}

}

+ 2
- 3
weaver/src/org/aspectj/weaver/bcel/BcelCflowCounterFieldAdder.java View File

@@ -13,7 +13,6 @@
package org.aspectj.weaver.bcel;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.generic.FieldGen;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionList;
@@ -44,10 +43,10 @@ public class BcelCflowCounterFieldAdder extends BcelTypeMunger {

// Create the field declaration.
// Something like: "public static final CflowCounter ajc$cflowCounter$0;"
Field f = new FieldGen(cflowCounterField.getModifiers(),
FieldGen f = new FieldGen(cflowCounterField.getModifiers(),
BcelWorld.makeBcelType(cflowCounterField.getReturnType()),
cflowCounterField.getName(),
gen.getConstantPoolGen()).getField();
gen.getConstantPool());
gen.addField(f,getSourceLocation());


+ 2
- 3
weaver/src/org/aspectj/weaver/bcel/BcelCflowStackFieldAdder.java View File

@@ -14,7 +14,6 @@
package org.aspectj.weaver.bcel;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.generic.FieldGen;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionList;
@@ -36,10 +35,10 @@ public class BcelCflowStackFieldAdder extends BcelTypeMunger {
LazyClassGen gen = weaver.getLazyClassGen();
if (!gen.getType().equals(cflowStackField.getDeclaringType())) return false;

Field f = new FieldGen(cflowStackField.getModifiers(),
FieldGen f = new FieldGen(cflowStackField.getModifiers(),
BcelWorld.makeBcelType(cflowStackField.getReturnType()),
cflowStackField.getName(),
gen.getConstantPoolGen()).getField();
gen.getConstantPool());
gen.addField(f,getSourceLocation());

LazyMethodGen clinit = gen.getAjcPreClinit(); //StaticInitializer();

+ 101
- 113
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java View File

@@ -27,45 +27,29 @@ import java.util.Properties;
import java.util.Set;

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;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.generic.FieldGen;
import org.aspectj.apache.bcel.generic.FieldInstruction;
import org.aspectj.apache.bcel.generic.GOTO;
import org.aspectj.apache.bcel.generic.GOTO_W;
import org.aspectj.apache.bcel.generic.INVOKESPECIAL;
import org.aspectj.apache.bcel.generic.IndexedInstruction;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionBranch;
import org.aspectj.apache.bcel.generic.InstructionCP;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionSelect;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.InvokeInstruction;
import org.aspectj.apache.bcel.generic.LineNumberTag;
import org.aspectj.apache.bcel.generic.LocalVariableInstruction;
import org.aspectj.apache.bcel.generic.LocalVariableTag;
import org.aspectj.apache.bcel.generic.MONITORENTER;
import org.aspectj.apache.bcel.generic.MONITOREXIT;
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;
import org.aspectj.apache.bcel.generic.RET;
import org.aspectj.apache.bcel.generic.ReturnInstruction;
import org.aspectj.apache.bcel.generic.Select;
import org.aspectj.apache.bcel.generic.StoreInstruction;
import org.aspectj.apache.bcel.generic.Tag;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;
@@ -76,6 +60,7 @@ import org.aspectj.bridge.context.ContextToken;
import org.aspectj.util.PartialOrder;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjcMemberMaker;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.AsmRelationshipProvider;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ConcreteTypeMunger;
@@ -102,6 +87,7 @@ import org.aspectj.weaver.patterns.ExactTypePattern;
import org.aspectj.weaver.tools.Trace;
import org.aspectj.weaver.tools.TraceFactory;


class BcelClassWeaver implements IClassWeaver {

private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelClassWeaver.class);
@@ -131,7 +117,7 @@ class BcelClassWeaver implements IClassWeaver {

private final BcelObjectType ty; // alias of clazz.getType()
private final BcelWorld world; // alias of ty.getWorld()
private final ConstantPoolGen cpg; // alias of clazz.getConstantPoolGen()
private final ConstantPool cpg; // alias of clazz.getConstantPoolGen()
private final InstructionFactory fact; // alias of clazz.getFactory();

@@ -174,7 +160,7 @@ class BcelClassWeaver implements IClassWeaver {
this.typeMungers = typeMungers;
this.lateTypeMungers = lateTypeMungers;
this.ty = clazz.getBcelObjectType();
this.cpg = clazz.getConstantPoolGen();
this.cpg = clazz.getConstantPool();
this.fact = clazz.getFactory();
fastMatchShadowMungers(shadowMungers);
@@ -799,8 +785,8 @@ class BcelClassWeaver implements IClassWeaver {
}

if (annotationsToAdd==null) annotationsToAdd = new ArrayList();
Annotation a = decaM.getAnnotationX().getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true);
AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true);
annotationsToAdd.add(ag);
mg.addAnnotation(decaM.getAnnotationX());
@@ -832,9 +818,10 @@ class BcelClassWeaver implements IClassWeaver {
}
if (annotationsToAdd==null) annotationsToAdd = new ArrayList();
Annotation a = decaM.getAnnotationX().getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true);
annotationsToAdd.add(ag);
AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation();
//CUSTARD superfluous?
//AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true);
annotationsToAdd.add(a);
mg.addAnnotation(decaM.getAnnotationX());
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod());
@@ -849,7 +836,7 @@ class BcelClassWeaver implements IClassWeaver {
}
if (annotationsToAdd!=null) {
Method oldMethod = mg.getMethod();
MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPoolGen(),false);// dont use tags, they won't get repaired like for woven methods.
MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPool(),false);// dont use tags, they won't get repaired like for woven methods.
for (Iterator iter = annotationsToAdd.iterator(); iter.hasNext();) {
AnnotationGen a = (AnnotationGen) iter.next();
myGen.addAnnotation(a);
@@ -1086,9 +1073,9 @@ class BcelClassWeaver implements IClassWeaver {
return isChanged;
}
private boolean dontAddTwice(DeclareAnnotation decaF, Annotation [] dontAddMeTwice){
private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX [] dontAddMeTwice){
for (int i = 0; i < dontAddMeTwice.length; i++){
Annotation ann = dontAddMeTwice[i];
AnnotationX ann = dontAddMeTwice[i];
if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())){
//dontAddMeTwice[i] = null; // incase it really has been added twice!
return true;
@@ -1130,18 +1117,18 @@ class BcelClassWeaver implements IClassWeaver {
List decaFs = getMatchingSubset(allDecafs,clazz.getType());
if (decaFs.isEmpty()) return false; // nothing more to do
Field[] fields = clazz.getFieldGens();
List fields = clazz.getFieldGens();
if (fields!=null) {
Set unusedDecafs = new HashSet();
unusedDecafs.addAll(decaFs);
for (int fieldCounter = 0;fieldCounter<fields.length;fieldCounter++) {
BcelField aBcelField = new BcelField(clazz.getBcelObjectType(),fields[fieldCounter]);
for (int fieldCounter = 0;fieldCounter<fields.size();fieldCounter++) {
BcelField aBcelField = (BcelField)fields.get(fieldCounter);//new BcelField(clazz.getBcelObjectType(),fields[fieldCounter]);
if (!aBcelField.getName().startsWith(NameMangler.PREFIX)) {
// Single first pass
List worthRetrying = new ArrayList();
boolean modificationOccured = false;
Annotation [] dontAddMeTwice = fields[fieldCounter].getAnnotations();
AnnotationX[] dontAddMeTwice = aBcelField.getAnnotations();
// go through all the declare @field statements
for (Iterator iter = decaFs.iterator(); iter.hasNext();) {
@@ -1159,22 +1146,22 @@ class BcelClassWeaver implements IClassWeaver {
if(decaF.getAnnotationX().isRuntimeVisible()){ // isAnnotationWithRuntimeRetention(clazz.getJavaClass(world))){
//if(decaF.getAnnotationTypeX().isAnnotationWithRuntimeRetention(world)){
// it should be runtime visible, so put it on the Field
Annotation a = decaF.getAnnotationX().getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true);
FieldGen myGen = new FieldGen(fields[fieldCounter],clazz.getConstantPoolGen());
myGen.addAnnotation(ag);
Field newField = myGen.getField();
// Annotation a = decaF.getAnnotationX().getBcelAnnotation();
// AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true);
// FieldGen myGen = new FieldGen(fields[fieldCounter],clazz.getConstantPoolGen());
// myGen.addAnnotation(ag);
// Field newField = myGen.getField();
aBcelField.addAnnotation(decaF.getAnnotationX());
clazz.replaceField(fields[fieldCounter],newField);
fields[fieldCounter]=newField;
// clazz.replaceField(fields[fieldCounter],newField);
// fields[fieldCounter]=newField;
} else{
aBcelField.addAnnotation(decaF.getAnnotationX());
}
}
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),fields[fieldCounter]);
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs());
reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF);
isChanged = true;
modificationOccured = true;
@@ -1202,7 +1189,7 @@ class BcelClassWeaver implements IClassWeaver {
continue; // skip this one...
}
aBcelField.addAnnotation(decaF.getAnnotationX());
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),fields[fieldCounter]);
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs());
isChanged = true;
modificationOccured = true;
forRemoval.add(decaF);
@@ -1270,13 +1257,13 @@ class BcelClassWeaver implements IClassWeaver {
}
// TAG: WeavingMessage
private void reportFieldAnnotationWeavingMessage(LazyClassGen clazz, Field[] fields, int fieldCounter, DeclareAnnotation decaF) {
private void reportFieldAnnotationWeavingMessage(LazyClassGen clazz, List fields, int fieldCounter, DeclareAnnotation decaF) {
if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)){
Field theField = fields[fieldCounter];
BcelField theField = (BcelField)fields.get(fieldCounter);
world.getMessageHandler().handleMessage(
WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES,
new String[]{
theField.toString() + "' of type '" + clazz.getName(),
theField.getFieldAsIs().toString() + "' of type '" + clazz.getName(),
clazz.getFileName(),
decaF.getAnnotationString(),
"field",
@@ -1389,7 +1376,7 @@ class BcelClassWeaver implements IClassWeaver {
}

private boolean isThisCall(InstructionHandle ih) {
INVOKESPECIAL inst = (INVOKESPECIAL) ih.getInstruction();
InvokeInstruction inst = (InvokeInstruction) ih.getInstruction();
return inst.getClassName(cpg).equals(clazz.getName());
}

@@ -1520,7 +1507,7 @@ class BcelClassWeaver implements IClassWeaver {
InstructionHandle walker = body.getStart();
List rets = new ArrayList();
while (walker!=null) {
if (walker.getInstruction() instanceof ReturnInstruction) {
if (walker.getInstruction().isReturnInstruction()) {
rets.add(walker);
}
walker = walker.getNext();
@@ -1549,10 +1536,10 @@ class BcelClassWeaver implements IClassWeaver {
// ignore
} else if (targeter instanceof LineNumberTag) {
// ignore
} else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
// move it...
targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof BranchInstruction) {
// } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) {
// // move it...
// targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof InstructionBranch) {
// move it
targeter.updateTarget(element, monitorExitBlockStart);
} else {
@@ -1612,8 +1599,8 @@ class BcelClassWeaver implements IClassWeaver {
parttwo.append(InstructionFactory.MONITORENTER);
String fieldname = synchronizedMethod.getEnclosingClass().allocateField("class$");
Field f = new FieldGen(Modifier.STATIC | Modifier.PRIVATE,
Type.getType(Class.class),fieldname,synchronizedMethod.getEnclosingClass().getConstantPoolGen()).getField();
FieldGen f = new FieldGen(Modifier.STATIC | Modifier.PRIVATE,
Type.getType(Class.class),fieldname,synchronizedMethod.getEnclosingClass().getConstantPool());
synchronizedMethod.getEnclosingClass().addField(f, null);
// 10: invokestatic #44; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
@@ -1699,7 +1686,7 @@ class BcelClassWeaver implements IClassWeaver {
InstructionHandle walker = body.getStart();
List rets = new ArrayList();
while (walker!=null) { //!walker.equals(body.getEnd())) {
if (walker.getInstruction() instanceof ReturnInstruction) {
if (walker.getInstruction().isReturnInstruction()) {
rets.add(walker);
}
walker = walker.getNext();
@@ -1729,10 +1716,10 @@ class BcelClassWeaver implements IClassWeaver {
// ignore
} else if (targeter instanceof LineNumberTag) {
// ignore
} else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
// move it...
targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof BranchInstruction) {
// } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
// // move it...
// targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof InstructionBranch) {
// move it
targeter.updateTarget(element, monitorExitBlockStart);
} else {
@@ -1807,7 +1794,7 @@ class BcelClassWeaver implements IClassWeaver {
InstructionHandle walker = body.getStart();
List rets = new ArrayList();
while (walker!=null) { //!walker.equals(body.getEnd())) {
if (walker.getInstruction() instanceof ReturnInstruction) {
if (walker.getInstruction().isReturnInstruction()) {
rets.add(walker);
}
walker = walker.getNext();
@@ -1837,10 +1824,10 @@ class BcelClassWeaver implements IClassWeaver {
// ignore
} else if (targeter instanceof LineNumberTag) {
// ignore
} else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
// move it...
targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof BranchInstruction) {
// } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
// // move it...
// targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof InstructionBranch) {
// move it
targeter.updateTarget(element, monitorExitBlockStart);
} else {
@@ -1899,8 +1886,8 @@ class BcelClassWeaver implements IClassWeaver {
InstructionList sourceList = donor.getBody();

Map srcToDest = new HashMap();
ConstantPoolGen donorCpg = donor.getEnclosingClass().getConstantPoolGen();
ConstantPoolGen recipientCpg = recipient.getEnclosingClass().getConstantPoolGen();
ConstantPool donorCpg = donor.getEnclosingClass().getConstantPool();
ConstantPool recipientCpg = recipient.getEnclosingClass().getConstantPool();
boolean isAcrossClass = donorCpg != recipientCpg;
@@ -1912,11 +1899,13 @@ class BcelClassWeaver implements IClassWeaver {
{
Instruction fresh = Utility.copyInstruction(src.getInstruction());
InstructionHandle dest;
if (fresh instanceof CPInstruction) {
// OPTIMIZE optimize this stuff?
if (fresh.isConstantPoolInstruction()) {
// need to reset index to go to new constant pool. This is totally
// a computation leak... we're testing this LOTS of times. Sigh.
if (isAcrossClass) {
CPInstruction cpi = (CPInstruction) fresh;
InstructionCP cpi = (InstructionCP) fresh;
cpi.setIndex(
recipientCpg.addConstant(
donorCpg.getConstant(cpi.getIndex()),
@@ -1925,19 +1914,20 @@ class BcelClassWeaver implements IClassWeaver {
}
if (src.getInstruction() == Range.RANGEINSTRUCTION) {
dest = ret.append(Range.RANGEINSTRUCTION);
} else if (fresh instanceof ReturnInstruction) {
} else if (fresh.isReturnInstruction()) {
if (keepReturns) {
dest = ret.append(fresh);
} else {
dest =
ret.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end));
}
} else if (fresh instanceof BranchInstruction) {
dest = ret.append((BranchInstruction) fresh);
} else if (fresh instanceof InstructionBranch) {
dest = ret.append((InstructionBranch) fresh);
} else if (
fresh instanceof LocalVariableInstruction || fresh instanceof RET) {
IndexedInstruction indexed = (IndexedInstruction) fresh;
int oldIndex = indexed.getIndex();
fresh.isLocalVariableInstruction() || fresh instanceof RET) {
// IndexedInstruction indexed = (IndexedInstruction) fresh;
int oldIndex = fresh.getIndex();
int freshIndex;
if (!frameEnv.hasKey(oldIndex)) {
freshIndex = recipient.allocateLocal(2);
@@ -1945,7 +1935,7 @@ class BcelClassWeaver implements IClassWeaver {
} else {
freshIndex = frameEnv.get(oldIndex);
}
indexed.setIndex(freshIndex);
fresh.setIndex(freshIndex);
dest = ret.append(fresh);
} else {
dest = ret.append(fresh);
@@ -1962,8 +1952,8 @@ class BcelClassWeaver implements IClassWeaver {
Instruction inst = dest.getInstruction();
// retarget branches
if (inst instanceof BranchInstruction) {
BranchInstruction branch = (BranchInstruction) inst;
if (inst instanceof InstructionBranch) {
InstructionBranch branch = (InstructionBranch) inst;
InstructionHandle oldTarget = branch.getTarget();
InstructionHandle newTarget =
(InstructionHandle) srcToDest.get(oldTarget);
@@ -1972,8 +1962,8 @@ class BcelClassWeaver implements IClassWeaver {
// this was a return instruction we previously replaced
} else {
branch.setTarget(newTarget);
if (branch instanceof Select) {
Select select = (Select) branch;
if (branch instanceof InstructionSelect) {
InstructionSelect select = (InstructionSelect) branch;
InstructionHandle[] oldTargets = select.getTargets();
for (int k = oldTargets.length - 1; k >= 0; k--) {
select.setTarget(
@@ -2056,7 +2046,7 @@ class BcelClassWeaver implements IClassWeaver {
InstructionHandle dest;
if (src.getInstruction() == Range.RANGEINSTRUCTION) {
dest = newList.append(Range.RANGEINSTRUCTION);
} else if (fresh instanceof ReturnInstruction) {
} else if (fresh.isReturnInstruction()) {
if (keepReturns) {
newList.append(InstructionFactory.createLoad(monitorVarType,monitorVarSlot));
newList.append(InstructionConstants.MONITOREXIT);
@@ -2065,12 +2055,12 @@ class BcelClassWeaver implements IClassWeaver {
dest =
newList.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end));
}
} else if (fresh instanceof BranchInstruction) {
dest = newList.append((BranchInstruction) fresh);
} else if (fresh instanceof InstructionBranch) {
dest = newList.append((InstructionBranch) fresh);
} else if (
fresh instanceof LocalVariableInstruction || fresh instanceof RET) {
IndexedInstruction indexed = (IndexedInstruction) fresh;
int oldIndex = indexed.getIndex();
fresh.isLocalVariableInstruction() || fresh instanceof RET) {
//IndexedInstruction indexed = (IndexedInstruction) fresh;
int oldIndex = fresh.getIndex();
int freshIndex;
// if (!frameEnv.hasKey(oldIndex)) {
// freshIndex = recipient.allocateLocal(2);
@@ -2078,7 +2068,7 @@ class BcelClassWeaver implements IClassWeaver {
// } else {
freshIndex = oldIndex;//frameEnv.get(oldIndex);
// }
indexed.setIndex(freshIndex);
fresh.setIndex(freshIndex);
dest = newList.append(fresh);
} else {
dest = newList.append(fresh);
@@ -2095,8 +2085,8 @@ class BcelClassWeaver implements IClassWeaver {
Instruction inst = dest.getInstruction();
// retarget branches
if (inst instanceof BranchInstruction) {
BranchInstruction branch = (BranchInstruction) inst;
if (inst instanceof InstructionBranch) {
InstructionBranch branch = (InstructionBranch) inst;
InstructionHandle oldTarget = branch.getTarget();
InstructionHandle newTarget =
(InstructionHandle) srcToDest.get(oldTarget);
@@ -2105,8 +2095,8 @@ class BcelClassWeaver implements IClassWeaver {
// this was a return instruction we previously replaced
} else {
branch.setTarget(newTarget);
if (branch instanceof Select) {
Select select = (Select) branch;
if (branch instanceof InstructionSelect) {
InstructionSelect select = (InstructionSelect) branch;
InstructionHandle[] oldTargets = select.getTargets();
for (int k = oldTargets.length - 1; k >= 0; k--) {
select.setTarget(
@@ -2278,11 +2268,11 @@ class BcelClassWeaver implements IClassWeaver {
if (start == null) return null;
Instruction inst = start.getInstruction();
if (inst instanceof INVOKESPECIAL
&& ((INVOKESPECIAL) inst).getName(cpg).equals("<init>")) {
if (inst.opcode==Constants.INVOKESPECIAL
&& ((InvokeInstruction) inst).getName(cpg).equals("<init>")) {
depth--;
if (depth == 0) return start;
} else if (inst instanceof NEW) {
} else if (inst.opcode==Constants.NEW) {
depth++;
}
start = start.getNext();
@@ -2470,7 +2460,7 @@ class BcelClassWeaver implements IClassWeaver {
if (er.getCatchType() == null) continue;
if (isInitFailureHandler(ih)) return;
if (!(ih.getInstruction() instanceof StoreInstruction) && ih.getInstruction().getOpcode()!=Constants.NOP) {
if (!ih.getInstruction().isStoreInstruction() && ih.getInstruction().getOpcode()!=Constants.NOP) {
// If using cobertura, the catch block stats with INVOKESTATIC rather than ASTORE, in order that the ranges
// for the methodcall and exceptionhandler shadows that occur at this same
// line, we need to modify the instruction list to split them - adding a
@@ -2508,7 +2498,7 @@ class BcelClassWeaver implements IClassWeaver {
) {
FieldInstruction fi = (FieldInstruction) i;
if (fi instanceof PUTFIELD || fi instanceof PUTSTATIC) {
if (fi.opcode==Constants.PUTFIELD || fi.opcode==Constants.PUTSTATIC) {
// check for sets of constant fields. We first check the previous
// instruction. If the previous instruction is a LD_WHATEVER (push
// constant on the stack) then we must resolve the field to determine
@@ -2537,12 +2527,12 @@ class BcelClassWeaver implements IClassWeaver {
}
} else if (i instanceof InvokeInstruction) {
InvokeInstruction ii = (InvokeInstruction) i;
if (ii.getMethodName(clazz.getConstantPoolGen()).equals("<init>")) {
if (ii.getMethodName(clazz.getConstantPool()).equals("<init>")) {
if (canMatch(Shadow.ConstructorCall))
match(
BcelShadow.makeConstructorCall(world, mg, ih, enclosingShadow),
shadowAccumulator);
} else if (ii instanceof INVOKESPECIAL) {
} else if (ii.opcode==Constants.INVOKESPECIAL) {
String onTypeName = ii.getClassName(cpg);
if (onTypeName.equals(mg.getEnclosingClass().getName())) {
// we are private
@@ -2553,26 +2543,25 @@ class BcelClassWeaver implements IClassWeaver {
} else {
matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator);
}
} else if (world.isJoinpointArrayConstructionEnabled() &&
(i instanceof NEWARRAY || i instanceof ANEWARRAY || i instanceof MULTIANEWARRAY)) {
} else if (world.isJoinpointArrayConstructionEnabled() && i.isArrayCreationInstruction()) {
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 (i.opcode==Constants.ANEWARRAY) {
// ANEWARRAY arrayInstruction = (ANEWARRAY)i;
ObjectType arrayType = i.getLoadClassType(clazz.getConstantPool());
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();
} else if (i.opcode==Constants.NEWARRAY) {
// NEWARRAY arrayInstruction = (NEWARRAY)i;
Type arrayType = i.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());
ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPool());
if (debug) System.err.println("Array type is "+arrayType);
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow);
match(ctorCallShadow,shadowAccumulator);
@@ -2587,9 +2576,9 @@ class BcelClassWeaver implements IClassWeaver {
// } else if (i instanceof AASTORE) {
// // ... magic required
} else if ( world.isJoinpointSynchronizationEnabled() &&
((i instanceof MONITORENTER) || (i instanceof MONITOREXIT))) {
((i.getOpcode()==Constants.MONITORENTER) || (i.getOpcode()==Constants.MONITOREXIT))) {
// if (canMatch(Shadow.Monitoring)) {
if (i instanceof MONITORENTER) {
if (i.getOpcode()==Constants.MONITORENTER) {
BcelShadow monitorEntryShadow = BcelShadow.makeMonitorEnter(world,mg,ih,enclosingShadow);
match(monitorEntryShadow,shadowAccumulator);
} else {
@@ -2607,8 +2596,8 @@ class BcelClassWeaver implements IClassWeaver {
// 'putstatic ajc$initFailureCause'. If it is then we are
// in the handler we created in AspectClinit.generatePostSyntheticCode()
InstructionHandle twoInstructionsAway = ih.getNext().getNext();
if (twoInstructionsAway.getInstruction() instanceof PUTSTATIC) {
String name = ((PUTSTATIC)twoInstructionsAway.getInstruction()).getFieldName(cpg);
if (twoInstructionsAway.getInstruction().opcode==Constants.PUTSTATIC) {
String name = ((FieldInstruction)twoInstructionsAway.getInstruction()).getFieldName(cpg);
if (name.equals(NameMangler.INITFAILURECAUSE_FIELD_NAME)) return true;
}
return false;
@@ -2794,13 +2783,12 @@ class BcelClassWeaver implements IClassWeaver {
effectiveSig.getShadowKind(), rm), shadowAccumulator);
}
} else {
if (canMatch(Shadow.MethodCall)) {
if (canMatch(Shadow.MethodCall))
match(
BcelShadow.makeMethodCall(world, mg, ih, enclosingShadow),
shadowAccumulator);
}
}
}
// static ... so all worlds will share the config for the first one created...
private static boolean checkedXsetForLowLevelContextCapturing = false;

+ 65
- 15
weaver/src/org/aspectj/weaver/bcel/BcelField.java View File

@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/


package org.aspectj.weaver.bcel;

import java.util.Collections;
@@ -20,10 +19,12 @@ import java.util.List;

import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.GenericSignatureParser;
import org.aspectj.apache.bcel.classfile.Signature;
import org.aspectj.apache.bcel.classfile.Synthetic;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.generic.FieldGen;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
@@ -31,6 +32,7 @@ import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;

final class BcelField extends ResolvedMemberImpl {
@@ -45,12 +47,14 @@ final class BcelField extends ResolvedMemberImpl {
private BcelObjectType bcelObjectType;
private UnresolvedType genericFieldType = null;
private boolean unpackedGenericSignature = false;
private boolean annotationsAdded = false;

BcelField(BcelObjectType declaringType, Field field) {
super(
FIELD,
declaringType.getResolvedTypeX(),
field.getAccessFlags(),
field.getModifiers(),
field.getName(),
field.getSignature());
this.field = field;
@@ -59,20 +63,41 @@ final class BcelField extends ResolvedMemberImpl {
unpackAttributes(world);
checkedExceptions = UnresolvedType.NONE;
}
/**
* Constructs an instance that wrappers a Field object, but where we do not (yet) have
* a BcelObjectType - usually because the containing type (and this field) are being
* constructed at runtime (so there is no .class file to retrieve).
*/
BcelField(String declaringTypeName, Field field,World world) {
super(FIELD,UnresolvedType.forName(declaringTypeName),field.getModifiers(),field.getName(),field.getSignature());
this.field = field;
this.world = world;
this.bcelObjectType = null;
unpackAttributes(world);
checkedExceptions = UnresolvedType.NONE;
}

// ----
private void unpackAttributes(World world) {
Attribute[] attrs = field.getAttributes();
List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),attrs, getSourceContext(world),world,bcelObjectType.getWeaverVersionAttribute());
as.addAll(AtAjAttributes.readAj5FieldAttributes(field, this, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler()));

for (Iterator iter = as.iterator(); iter.hasNext();) {
AjAttribute a = (AjAttribute) iter.next();
if (a instanceof AjAttribute.AjSynthetic) {
isAjSynthetic = true;
} else {
throw new BCException("weird field attribute " + a);
if (attrs!=null && attrs.length>0) {
List as = BcelAttributes.readAjAttributes(
getDeclaringType().getClassName(),
attrs,
getSourceContext(world),
world,
(bcelObjectType!=null?bcelObjectType.getWeaverVersionAttribute():WeaverVersionInfo.CURRENT));
as.addAll(AtAjAttributes.readAj5FieldAttributes(field, this, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler()));
for (Iterator iter = as.iterator(); iter.hasNext();) {
AjAttribute a = (AjAttribute) iter.next();
if (a instanceof AjAttribute.AjSynthetic) {
isAjSynthetic = true;
} else {
throw new BCException("weird field attribute " + a);
}
}
}
isAjSynthetic = false;
@@ -130,7 +155,7 @@ final class BcelField extends ResolvedMemberImpl {
private void ensureAnnotationTypesRetrieved() {
if (annotationTypes == null) {
Annotation annos[] = field.getAnnotations();
AnnotationGen annos[] = field.getAnnotations();
if (annos==null || annos.length==0) {
annotationTypes = Collections.EMPTY_SET;
annotations = AnnotationX.NONE;
@@ -138,7 +163,7 @@ final class BcelField extends ResolvedMemberImpl {
annotationTypes = new HashSet();
annotations = new AnnotationX[annos.length];
for (int i = 0; i < annos.length; i++) {
Annotation annotation = annos[i];
AnnotationGen annotation = annos[i];
annotationTypes.add(world.resolve(UnresolvedType.forSignature(annotation.getTypeSignature())));
annotations[i] = new AnnotationX(annotation,world);
}
@@ -160,11 +185,13 @@ final class BcelField extends ResolvedMemberImpl {
}
// Add it to the set of annotation types
annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(world));
annotationsAdded=true;
// FIXME asc this call here suggests we are managing the annotations at
// too many levels, here in BcelField we keep a set and in the lower 'field'
// object we keep a set - we should think about reducing this to one
// level??
field.addAnnotation(annotation.getBcelAnnotation());
//field.addAnnotation(annotation.getBcelAnnotation());
// FIXME CUSTARD
}
/**
@@ -176,6 +203,29 @@ final class BcelField extends ResolvedMemberImpl {
return genericFieldType;
}
public Field getFieldAsIs() { return field; }
// FIXME asc badly performing code ftw !
public Field getField(ConstantPool cpg) {
if (!annotationsAdded) return field;
FieldGen fg = new FieldGen(field,cpg);
AnnotationGen[] alreadyHas = fg.getAnnotations();
if (annotations!=null) {
for (int i = 0; i < annotations.length; i++) {
AnnotationX array_element = annotations[i];
boolean alreadyHasIt = false;
for (int j = 0; j < alreadyHas.length; j++) {
AnnotationGen gen = alreadyHas[j];
if (gen.getTypeName().equals(array_element.getTypeName())) alreadyHasIt = true;
}
if (!alreadyHasIt) fg.addAnnotation(new AnnotationGen(array_element.getBcelAnnotation(),cpg,true));
}
}
field = fg.getField();
annotationsAdded = false; // we are now correct again
return field;
}
private void unpackGenericSignature() {
if (unpackedGenericSignature) { return; }
if (!world.isInJava5Mode()) {

+ 95
- 53
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java View File

@@ -15,6 +15,7 @@ package org.aspectj.weaver.bcel;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -32,14 +33,15 @@ import org.aspectj.apache.bcel.classfile.LocalVariableTable;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Signature;
import org.aspectj.apache.bcel.classfile.Signature.TypeVariableSignature;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.SourceLocation;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedType;
@@ -52,12 +54,7 @@ import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSigna
public final class BcelMethod extends ResolvedMemberImpl {


private Method method;
private boolean isAjSynthetic;
private boolean isSynthetic;
private boolean knowIfSynthetic = false;
private ShadowMunger associatedShadowMunger;
private ResolvedPointcutDefinition preResolvedPointcut; // used when ajc has pre-resolved the pointcut of some @Advice
@@ -67,10 +64,26 @@ public final class BcelMethod extends ResolvedMemberImpl {
private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber;
private World world;
private BcelObjectType bcelObjectType;
private boolean parameterNamesInitialized = false;
private int bitflags;
private static final int KNOW_IF_SYNTHETIC = 0x0001;
private static final int PARAMETER_NAMES_INITIALIZED = 0x0002;
private static final int CAN_BE_PARAMETERIZED = 0x0004;
private static final int UNPACKED_GENERIC_SIGNATURE = 0x0008;
private static final int HAS_EFFECTIVE_SIGNATURE = 0x0010;
private static final int HAS_PRERESOLVED_POINTCUT = 0x0020;
private static final int IS_AJ_SYNTHETIC = 0x0040;
private static final int IS_SYNTHETIC = 0x0080;
private static final int IS_SYNTHETIC_INVERSE = 0x7f7f; // all bits but IS_SYNTHETIC (and topmost bit)
private static final int HAS_ASSOCIATED_SHADOWMUNGER = 0x0100;
private static final int HAS_GENERIC_RETPARAM_TYPES = 0x0200;
private static final int HAS_ANNOTATIONS = 0x0400;
private static final int HAVE_DETERMINED_ANNOTATIONS = 0x0800;
private static final int HAS_MD_LINE_NUMBER_ATTRIBUTE= 0x1000;

private boolean canBeParameterized = false;
// genericized version of return and parameter types
@@ -84,16 +97,15 @@ public final class BcelMethod extends ResolvedMemberImpl {
(method.getName().equals("<clinit>") ? STATIC_INITIALIZATION : METHOD),
declaringType.getResolvedTypeX(),
declaringType.isInterface()
? method.getAccessFlags() | Modifier.INTERFACE
: method.getAccessFlags(),
method.getName(),
? method.getModifiers() | Modifier.INTERFACE
: method.getModifiers(),
method.getName(),
method.getSignature());
this.method = method;
this.sourceContext = declaringType.getResolvedTypeX().getSourceContext();
this.world = declaringType.getResolvedTypeX().getWorld();
this.bcelObjectType = declaringType;
unpackJavaAttributes();
unpackAjAttributes(world);
unpackAjAttributes(bcelObjectType.getWorld());
}

// ----
@@ -135,12 +147,12 @@ public final class BcelMethod extends ResolvedMemberImpl {
typename.equals("org.aspectj.lang.annotation.Before") ||
typename.equals("org.aspectj.lang.annotation.Around") ||
typename.startsWith("org.aspectj.lang.annotation.After")) {
Annotation a = annotationX.getBcelAnnotation();
AnnotationGen a = annotationX.getBcelAnnotation();
if (a!=null) {
List values = a.getValues();
for (Iterator iterator = values.iterator(); iterator
.hasNext();) {
ElementNameValuePair nvPair = (ElementNameValuePair) iterator.next();
ElementNameValuePairGen nvPair = (ElementNameValuePairGen) iterator.next();
if (nvPair.getNameString().equals("argNames")) {
String argNames = nvPair.getValue().stringifyValue();
StringTokenizer argNameTokenizer = new StringTokenizer(argNames," ,");
@@ -195,7 +207,8 @@ public final class BcelMethod extends ResolvedMemberImpl {
associatedShadowMunger = ((AjAttribute.AdviceAttribute)a).reify(this, world);
// return;
} else if (a instanceof AjAttribute.AjSynthetic) {
isAjSynthetic = true;
bitflags|=IS_AJ_SYNTHETIC;
// isAjSynthetic = true;
} else if (a instanceof AjAttribute.EffectiveSignatureAttribute) {
//System.out.println("found effective: " + this);
effectiveSignature = (AjAttribute.EffectiveSignatureAttribute)a;
@@ -211,7 +224,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
// for testing - if we have this attribute, return it - will return null if it doesnt know anything
public AjAttribute[] getAttributes(String name) {
List results = new ArrayList();
List l = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(world),world,bcelObjectType.getWeaverVersionAttribute());
List l = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(bcelObjectType.getWorld()),bcelObjectType.getWorld(),bcelObjectType.getWeaverVersionAttribute());
for (Iterator iter = l.iterator(); iter.hasNext();) {
AjAttribute element = (AjAttribute) iter.next();
if (element.getNameString().equals(name)) results.add(element);
@@ -247,7 +260,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
}

public boolean isAjSynthetic() {
return isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX);
return (bitflags&IS_AJ_SYNTHETIC)!=0;//isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX);
}
//FIXME ??? needs an isSynthetic method
@@ -291,7 +304,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
return ret;
}
public Kind getKind() {
public MemberKind getKind() {
if (associatedShadowMunger != null) {
return ADVICE;
} else {
@@ -310,7 +323,11 @@ public final class BcelMethod extends ResolvedMemberImpl {
public AnnotationX[] getAnnotations() {
ensureAnnotationsRetrieved();
return annotations;
if ((bitflags&HAS_ANNOTATIONS)!=0) {
return annotations;
} else {
return AnnotationX.NONE;
}
}
public ResolvedType[] getAnnotationTypes() {
@@ -323,6 +340,7 @@ public final class BcelMethod extends ResolvedMemberImpl {

public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
ensureAnnotationsRetrieved();
if ((bitflags&HAS_ANNOTATIONS)==0) return null;
for (int i=0; i<annotations.length; i++) {
if (annotations[i].getTypeName().equals(ofType.getName())) return annotations[i];
}
@@ -331,51 +349,64 @@ public final class BcelMethod extends ResolvedMemberImpl {
public void addAnnotation(AnnotationX annotation) {
ensureAnnotationsRetrieved();
// Add it to the set of annotations
int len = annotations.length;
AnnotationX[] ret = new AnnotationX[len+1];
System.arraycopy(annotations, 0, ret, 0, len);
ret[len] = annotation;
annotations = ret;
if ((bitflags&HAS_ANNOTATIONS)==0) {
annotations = new AnnotationX[1];
annotations[0]=annotation;
} else {
// Add it to the set of annotations
int len = annotations.length;
AnnotationX[] ret = new AnnotationX[len+1];
System.arraycopy(annotations, 0, ret, 0, len);
ret[len] = annotation;
annotations = ret;
}
bitflags|=HAS_ANNOTATIONS;
// Add it to the set of annotation types
annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(world));
if (annotationTypes==Collections.EMPTY_SET) annotationTypes = new HashSet();
annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(bcelObjectType.getWorld()));
// FIXME asc looks like we are managing two 'bunches' of annotations, one
// here and one in the real 'method' - should we reduce it to one layer?
method.addAnnotation(annotation.getBcelAnnotation());
// method.addAnnotation(annotation.getBcelAnnotation());
}
private void ensureAnnotationsRetrieved() {
if (method == null) return; // must be ok, we have evicted it
if (annotationTypes == null || method.getAnnotations().length!=annotations.length) { // sometimes the list changes underneath us!
Annotation annos[] = method.getAnnotations();
annotationTypes = new HashSet();
annotations = new AnnotationX[annos.length];
for (int i = 0; i < annos.length; i++) {
Annotation annotation = annos[i];
annotationTypes.add(world.resolve(UnresolvedType.forSignature(annotation.getTypeSignature())));
annotations[i] = new AnnotationX(annotation,world);
}
}
if ((bitflags&HAVE_DETERMINED_ANNOTATIONS)!=0) return;
bitflags|=HAVE_DETERMINED_ANNOTATIONS;
AnnotationGen annos[] = method.getAnnotations();
if (annos.length!=0) {
annotationTypes = new HashSet();
annotations = new AnnotationX[annos.length];
for (int i = 0; i < annos.length; i++) {
AnnotationGen annotation = annos[i];
annotationTypes.add(bcelObjectType.getWorld().resolve(UnresolvedType.forSignature(annotation.getTypeSignature())));
annotations[i] = new AnnotationX(annotation,bcelObjectType.getWorld());
}
bitflags|=HAS_ANNOTATIONS;
} else {
annotationTypes=Collections.EMPTY_SET;
}
}
private void ensureParameterAnnotationsRetrieved() {
if (method == null) return; // must be ok, we have evicted it
Annotation[][] pAnns = method.getParameterAnnotations();
AnnotationGen[][] pAnns = method.getParameterAnnotations();
if (parameterAnnotationTypes==null || pAnns.length!=parameterAnnotationTypes.length) {
if (pAnns == Method.NO_PARAMETER_ANNOTATIONS) {
parameterAnnotationTypes = BcelMethod.NO_PARAMETER_ANNOTATION_TYPES;
parameterAnnotations = BcelMethod.NO_PARAMETER_ANNOTATIONXS;
} else {
Annotation annos[][] = method.getParameterAnnotations();
AnnotationGen annos[][] = method.getParameterAnnotations();
parameterAnnotations = new AnnotationX[annos.length][];
parameterAnnotationTypes = new ResolvedType[annos.length][];
for (int i=0;i<annos.length;i++) {
parameterAnnotations[i] = new AnnotationX[annos[i].length];
parameterAnnotationTypes[i] = new ResolvedType[annos[i].length];
for (int j=0;j<annos[i].length;j++) {
parameterAnnotations[i][j] = new AnnotationX(annos[i][j],world);
parameterAnnotationTypes[i][j] = world.resolve(UnresolvedType.forSignature(annos[i][j].getTypeSignature()));
parameterAnnotations[i][j] = new AnnotationX(annos[i][j],bcelObjectType.getWorld());
parameterAnnotationTypes[i][j] = bcelObjectType.getWorld().resolve(UnresolvedType.forSignature(annos[i][j].getTypeSignature()));
}
}
}
@@ -423,7 +454,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
private void unpackGenericSignature() {
if (unpackedGenericSignature) return;
unpackedGenericSignature = true;
if (!world.isInJava5Mode()) {
if (!bcelObjectType.getWorld().isInJava5Mode()) {
this.genericReturnType = getReturnType();
this.genericParameterTypes = getParameterTypes();
return;
@@ -443,7 +474,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
typeVariables[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable(
methodFtp,
mSig.formalTypeParameters,
world);
bcelObjectType.getWorld());
} catch (GenericSignatureFormatException e) {
// this is a development bug, so fail fast with good info
throw new IllegalStateException(
@@ -463,7 +494,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
try {
genericReturnType = BcelGenericSignatureToTypeXConverter.typeSignature2TypeX(
returnTypeSignature, formals,
world);
bcelObjectType.getWorld());
} catch (GenericSignatureFormatException e) {
// development bug, fail fast with good info
throw new IllegalStateException(
@@ -477,7 +508,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
try {
genericParameterTypes[i] =
BcelGenericSignatureToTypeXConverter.typeSignature2TypeX(
paramTypeSigs[i],formals,world);
paramTypeSigs[i],formals,bcelObjectType.getWorld());
} catch (GenericSignatureFormatException e) {
// development bug, fail fast with good info
throw new IllegalStateException(
@@ -508,27 +539,38 @@ public final class BcelMethod extends ResolvedMemberImpl {
}

public boolean isSynthetic() {
if (!knowIfSynthetic) workOutIfSynthetic();
return isSynthetic;
if ((bitflags&KNOW_IF_SYNTHETIC)==0) {
workOutIfSynthetic();
}
return (bitflags&IS_SYNTHETIC)!=0;//isSynthetic;
}

// Pre Java5 synthetic is an attribute 'Synthetic', post Java5 it is a modifier (4096 or 0x1000)
private void workOutIfSynthetic() {
knowIfSynthetic=true;
if ((bitflags&KNOW_IF_SYNTHETIC)!=0) return;
bitflags|=KNOW_IF_SYNTHETIC;
// knowIfSynthetic=true;
JavaClass jc = bcelObjectType.getJavaClass();
isSynthetic=false;
bitflags&=IS_SYNTHETIC_INVERSE; // unset the bit
// isSynthetic=false;
if (jc==null) return; // what the hell has gone wrong?
if (jc.getMajor()<49/*Java5*/) {
// synthetic is an attribute
String[] synthetics = getAttributeNames(false);
if (synthetics!=null) {
for (int i = 0; i < synthetics.length; i++) {
if (synthetics[i].equals("Synthetic")) {isSynthetic=true;break;}
if (synthetics[i].equals("Synthetic")) {
bitflags|=IS_SYNTHETIC;
// isSynthetic=true;
break;}
}
}
} else {
// synthetic is a modifier (4096)
isSynthetic = (modifiers&4096)!=0;
if ((modifiers&4096)!=0) {
bitflags|=IS_SYNTHETIC;
}
// isSynthetic = (modifiers&4096)!=0;
}
}

@@ -549,4 +591,4 @@ public final class BcelMethod extends ResolvedMemberImpl {
o.getMethod().getCode().getCodeString());
}

}
}

+ 32
- 22
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java View File

@@ -22,15 +22,16 @@ import java.util.Iterator;
import java.util.List;

import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.AttributeUtils;
import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Signature;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.weaver.AbstractReferenceTypeDelegate;
import org.aspectj.weaver.AjAttribute;
@@ -38,6 +39,7 @@ import org.aspectj.weaver.AjcMemberMaker;
import org.aspectj.weaver.AnnotationTargetKind;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedPointcutDefinition;
@@ -133,14 +135,19 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
// @AJ pc refs annotation in class hierarchy
resolvedTypeX.setDelegate(this);

if (resolvedTypeX.getSourceContext()==SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) {
setSourceContext(new SourceContextImpl(this));
ISourceContext sourceContext = resolvedTypeX.getSourceContext();
if (sourceContext==SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) {
sourceContext = new SourceContextImpl(this);
setSourceContext(sourceContext);
}
// this should only ever be java.lang.Object which is
// the only class in Java-1.4 with no superclasses
isObject = (javaClass.getSuperclassNameIndex() == 0);
ensureAspectJAttributesUnpacked();
// if (sourceContext instanceof SourceContextImpl) {
// ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.getSourceFileName());
// }
setSourcefilename(javaClass.getSourceFileName());
}
@@ -157,7 +164,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
isAnnotation = javaClass.isAnnotation();
isAnonymous = javaClass.isAnonymous();
isNested = javaClass.isNested();
modifiers = javaClass.getAccessFlags();
modifiers = javaClass.getModifiers();
superclassName = javaClass.getSuperclassName();
className = javaClass.getClassName();
cachedGenericClassTypeSignature = null;
@@ -193,6 +200,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return res;
}
public World getWorld() {
return getResolvedTypeX().getWorld();
}
/**
* Retrieves the declared interfaces - this allows for the generic signature on a type. If specified
* then the generic signature is used to work out the types - this gets around the results of
@@ -357,6 +368,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
if (getResolvedTypeX().getSourceContext() instanceof SourceContextImpl) {
AjAttribute.SourceContextAttribute sca = (AjAttribute.SourceContextAttribute)a;
((SourceContextImpl)getResolvedTypeX().getSourceContext()).configureFromAttribute(sca.getSourceFileName(),sca.getLineBreaks());
setSourcefilename(sca.getSourceFileName());
}
} else if (a instanceof AjAttribute.WeaverVersionInfo) {
wvInfo = (AjAttribute.WeaverVersionInfo)a; // Set the weaver version used to build this type
@@ -567,8 +580,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
if (ax.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) {
List values = ax.getBcelAnnotation().getValues();
for (Iterator it = values.iterator(); it.hasNext();) {
ElementNameValuePair element = (ElementNameValuePair) it.next();
EnumElementValue v = (EnumElementValue)element.getValue();
ElementNameValuePairGen element = (ElementNameValuePairGen) it.next();
EnumElementValueGen v = (EnumElementValueGen)element.getValue();
retentionPolicy = v.getEnumValueString();
return retentionPolicy;
}
@@ -596,15 +609,15 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
annotationTargetKinds = null; // null means we have no idea or the @Target annotation hasn't been used
List targetKinds = new ArrayList();
if (isAnnotation()) {
AnnotationX[] annotationsOnThisType = getAnnotations();
AnnotationGen[] annotationsOnThisType = javaClass.getAnnotations();
for (int i = 0; i < annotationsOnThisType.length; i++) {
Annotation a = annotationsOnThisType[i].getBcelAnnotation();
AnnotationGen a = annotationsOnThisType[i];
if (a.getTypeName().equals(UnresolvedType.AT_TARGET.getName())) {
ArrayElementValue arrayValue = (ArrayElementValue)((ElementNameValuePair)a.getValues().get(0)).getValue();
ElementValue[] evs = arrayValue.getElementValuesArray();
ArrayElementValueGen arrayValue = (ArrayElementValueGen)((ElementNameValuePairGen)a.getValues().get(0)).getValue();
ElementValueGen[] evs = arrayValue.getElementValuesArray();
if (evs!=null) {
for (int j = 0; j < evs.length; j++) {
String targetKind = ((EnumElementValue)evs[j]).getEnumValueString();
String targetKind = ((EnumElementValueGen)evs[j]).getEnumValueString();
if (targetKind.equals("ANNOTATION_TYPE")) { targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE);
} else if (targetKind.equals("CONSTRUCTOR")) { targetKinds.add(AnnotationTargetKind.CONSTRUCTOR);
} else if (targetKind.equals("FIELD")) { targetKinds.add(AnnotationTargetKind.FIELD);
@@ -629,7 +642,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
private void ensureAnnotationsUnpacked() {
if (annotationTypes == null) {
Annotation annos[] = javaClass.getAnnotations();
AnnotationGen annos[] = javaClass.getAnnotations();
if (annos==null || annos.length==0) {
annotationTypes = ResolvedType.NONE;
annotations = AnnotationX.NONE;
@@ -638,7 +651,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
annotationTypes = new ResolvedType[annos.length];
annotations = new AnnotationX[annos.length];
for (int i = 0; i < annos.length; i++) {
Annotation annotation = annos[i];
AnnotationGen annotation = annos[i];
annotationTypes[i] = w.resolve(UnresolvedType.forSignature(annotation.getTypeSignature()));
annotations[i] = new AnnotationX(annotation,w);
}
@@ -750,11 +763,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
private void ensureGenericInfoProcessed() {
if ((bitflag & DISCOVERED_DECLARED_SIGNATURE)!=0) return;
bitflag |= DISCOVERED_DECLARED_SIGNATURE;
Attribute[] as = javaClass.getAttributes();
for (int i = 0; i < as.length && declaredSignature==null; i++) {
Attribute attribute = as[i];
if (attribute instanceof Signature) declaredSignature = ((Signature)attribute).getSignature();
}
Signature sigAttr = AttributeUtils.getSignatureAttribute(javaClass.getAttributes());
declaredSignature = (sigAttr==null?null:sigAttr.getSignature());
if (declaredSignature!=null) isGenericType= (declaredSignature.charAt(0)=='<');
}

+ 28
- 32
weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java View File

@@ -12,16 +12,12 @@
package org.aspectj.weaver.bcel;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.generic.ATHROW;
import org.aspectj.apache.bcel.generic.BranchInstruction;
import org.aspectj.apache.bcel.generic.InstructionBranch;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.NOP;
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.ReferenceType;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.weaver.AjAttribute;
@@ -170,11 +166,11 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {

//FIXME Alex percflowX is not using this one but AJ code style does generate it so..
ResolvedMember failureFieldInfo = AjcMemberMaker.initFailureCauseField(aspectType);
classGen.addField(makeFieldGen(classGen, failureFieldInfo).getField(), null);
classGen.addField(makeFieldGen(classGen, failureFieldInfo), null);

if (kind == PerClause.SINGLETON) {
ResolvedMember perSingletonFieldInfo = AjcMemberMaker.perSingletonField(aspectType);
classGen.addField(makeFieldGen(classGen, perSingletonFieldInfo).getField(), null);
classGen.addField(makeFieldGen(classGen, perSingletonFieldInfo), null);
// pr144602 - don't need to do this, PerObjectInterface munger will do it
// } else if (kind == PerClause.PEROBJECT) {
// ResolvedMember perObjectFieldInfo = AjcMemberMaker.perObjectField(aspectType, aspectType);
@@ -183,10 +179,10 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
// // it should be done here.
} else if (kind == PerClause.PERCFLOW) {
ResolvedMember perCflowFieldInfo = AjcMemberMaker.perCflowField(aspectType);
classGen.addField(makeFieldGen(classGen, perCflowFieldInfo).getField(), null);
classGen.addField(makeFieldGen(classGen, perCflowFieldInfo), null);
} else if (kind == PerClause.PERTYPEWITHIN) {
ResolvedMember perTypeWithinForField = AjcMemberMaker.perTypeWithinWithinTypeField(aspectType, aspectType);
classGen.addField(makeFieldGen(classGen, perTypeWithinForField).getField(), null);
classGen.addField(makeFieldGen(classGen, perTypeWithinForField), null);
// } else {
// throw new Error("Should not happen - no such kind " + kind.toString());
}
@@ -200,11 +196,11 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {

InstructionList il = method.getBody();
il.append(Utility.createGet(factory, AjcMemberMaker.perSingletonField(aspectType)));
BranchInstruction ifNotNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
InstructionBranch ifNotNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
il.append(ifNotNull);
il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName()));
il.append(InstructionConstants.DUP);
il.append(new PUSH(classGen.getConstantPoolGen(), aspectType.getName()));
il.append(InstructionFactory.PUSH(classGen.getConstantPool(), aspectType.getName()));
il.append(Utility.createGet(factory, AjcMemberMaker.initFailureCauseField(aspectType)));
il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, new Type[] { Type.STRING, new ObjectType("java.lang.Throwable") }, Constants.INVOKESPECIAL));
il.append(InstructionConstants.ATHROW);
@@ -221,11 +217,11 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {

InstructionList il = method.getBody();
il.append(Utility.createGet(factory, AjcMemberMaker.perSingletonField(aspectType)));
BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
InstructionBranch ifNull = (InstructionBranch)InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
il.append(ifNull);
il.append(new PUSH(classGen.getConstantPoolGen(), true));
il.append(InstructionFactory.PUSH(classGen.getConstantPool(), true));
il.append(InstructionFactory.createReturn(Type.INT));
InstructionHandle ifElse = il.append(new PUSH(classGen.getConstantPoolGen(), false));
InstructionHandle ifElse = il.append(InstructionFactory.PUSH(classGen.getConstantPool(), false));
il.append(InstructionFactory.createReturn(Type.INT));
ifNull.setTarget(ifElse);
}
@@ -248,7 +244,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
LazyMethodGen clinit = classGen.getStaticInitializer();
il = new InstructionList();
InstructionHandle tryStart = il.append(factory.createInvoke(aspectType.getName(), NameMangler.AJC_POST_CLINIT_NAME, Type.VOID, Type.NO_ARGS, Constants.INVOKESTATIC));
BranchInstruction tryEnd = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
InstructionBranch tryEnd = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
il.append(tryEnd);
InstructionHandle handler = il.append(InstructionConstants.ASTORE_0);
il.append(InstructionConstants.ALOAD_0);
@@ -258,10 +254,10 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {

// replace the original "return" with a "nop"
//TODO AV - a bit odd, looks like Bcel alters bytecode and has a IMPDEP1 in its representation
if (clinit.getBody().getEnd().getInstruction().getOpcode() == Constants.IMPDEP1) {
clinit.getBody().getEnd().getPrev().setInstruction(new NOP());
if (clinit.getBody().getEnd().getInstruction().opcode == Constants.IMPDEP1) {
clinit.getBody().getEnd().getPrev().setInstruction(InstructionConstants.NOP);
}
clinit.getBody().getEnd().setInstruction(new NOP());
clinit.getBody().getEnd().setInstruction(InstructionConstants.NOP);
clinit.getBody().append(il);

clinit.addExceptionHandler(
@@ -279,22 +275,22 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
InstructionList il = method.getBody();
il.append(InstructionConstants.ALOAD_0);
il.append(factory.createInstanceOf(interfaceType));
BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
InstructionBranch ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
il.append(ifEq);
il.append(InstructionConstants.ALOAD_0);
il.append(factory.createCheckCast(interfaceType));
il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType)));
il.append(InstructionConstants.DUP);
BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
InstructionBranch ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
il.append(ifNull);
il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(aspectType)));
InstructionHandle ifNullElse = il.append(new POP());
InstructionHandle ifNullElse = il.append(InstructionConstants.POP);
ifNull.setTarget(ifNullElse);
InstructionHandle ifEqElse = il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName()));
ifEq.setTarget(ifEqElse);
il.append(InstructionConstants.DUP);
il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
il.append(new ATHROW());
il.append(InstructionConstants.ATHROW);
}

private void generatePerObjectHasAspectMethod(LazyClassGen classGen) {
@@ -307,12 +303,12 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
InstructionList il = method.getBody();
il.append(InstructionConstants.ALOAD_0);
il.append(factory.createInstanceOf(interfaceType));
BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
InstructionBranch ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
il.append(ifEq);
il.append(InstructionConstants.ALOAD_0);
il.append(factory.createCheckCast(interfaceType));
il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType)));
BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
InstructionBranch ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
il.append(ifNull);
il.append(InstructionConstants.ICONST_1);
il.append(InstructionFactory.createReturn(Type.INT));
@@ -332,12 +328,12 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
InstructionList il = method.getBody();
il.append(InstructionConstants.ALOAD_0);
il.append(factory.createInstanceOf(interfaceType));
BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
InstructionBranch ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
il.append(ifEq);
il.append(InstructionConstants.ALOAD_0);
il.append(factory.createCheckCast(interfaceType));
il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType)));
BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
il.append(ifNonNull);
il.append(InstructionConstants.ALOAD_0);
il.append(factory.createCheckCast(interfaceType));
@@ -449,11 +445,11 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
));
il.append(InstructionConstants.ASTORE_1);
il.append(InstructionConstants.ALOAD_1);
BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
il.append(ifNonNull);
il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName()));
il.append(InstructionConstants.DUP);
il.append(new PUSH(classGen.getConstantPoolGen(), aspectType.getName()));
il.append(InstructionFactory.PUSH(classGen.getConstantPool(), aspectType.getName()));
il.append(InstructionConstants.ACONST_NULL);
il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, new Type[] { Type.STRING, new ObjectType("java.lang.Throwable") }, Constants.INVOKESPECIAL));
il.append(InstructionConstants.ATHROW);
@@ -500,7 +496,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
Constants.INVOKESTATIC,
AjcMemberMaker.perTypeWithinGetInstance(aspectType)
));
BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
InstructionBranch ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null);
il.append(ifNull);
il.append(InstructionConstants.ICONST_1);
il.append(InstructionConstants.IRETURN);
@@ -525,7 +521,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {

InstructionList il = method.getBody();
InstructionHandle tryStart = il.append(InstructionConstants.ALOAD_0);
il.append(new PUSH(factory.getConstantPool(), NameMangler.perTypeWithinLocalAspectOf(aspectType)));
il.append(InstructionFactory.PUSH(factory.getConstantPool(), NameMangler.perTypeWithinLocalAspectOf(aspectType)));
il.append(InstructionConstants.ACONST_NULL);//Class[] for "getDeclaredMethod"
il.append(factory.createInvoke(
"java/lang/Class",
@@ -588,9 +584,9 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
methodGen.makeSynthetic();
}
methodGen.addAttribute(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.AjSynthetic(),
methodGen.getEnclosingClass().getConstantPoolGen()
methodGen.getEnclosingClass().getConstantPool()
)
);
}

+ 46
- 75
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java View File

@@ -24,40 +24,28 @@ 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;
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.DUP_X2;
import org.aspectj.apache.bcel.classfile.ConstantPool;
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;
import org.aspectj.apache.bcel.generic.InstructionBranch;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionLV;
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.LineNumberTag;
import org.aspectj.apache.bcel.generic.LoadInstruction;
import org.aspectj.apache.bcel.generic.LocalVariableTag;
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.PUSH;
import org.aspectj.apache.bcel.generic.RETURN;
import org.aspectj.apache.bcel.generic.ReturnInstruction;
import org.aspectj.apache.bcel.generic.SWAP;
import org.aspectj.apache.bcel.generic.StoreInstruction;
import org.aspectj.apache.bcel.generic.TargetLostException;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.AjcMemberMaker;
@@ -141,7 +129,6 @@ public class BcelShadow extends Shadow {
private ShadowRange range;
private final BcelWorld world;
private final LazyMethodGen enclosingMethod;
// private boolean fallsThrough; //XXX not used anymore
// SECRETAPI - for testing, this will tell us if the optimization succeeded *on the last shadow processed*
public static boolean appliedLazyTjpOptimization;
@@ -150,24 +137,15 @@ public class BcelShadow extends Shadow {
// from the signature (pr109728) (1.4 declaring type issue)
private String actualInstructionTargetType;

// ---- initialization
/**
* This generates an unassociated shadow, rooted in a particular method but not rooted
* This generates an unassociated shadow, rooted in a particular method but not rooted
* to any particular point in the code. It should be given to a rooted ShadowRange
* in the {@link ShadowRange#associateWithShadow(BcelShadow)} method.
*/
public BcelShadow(
BcelWorld world,
Kind kind,
Member signature,
LazyMethodGen enclosingMethod,
BcelShadow enclosingShadow)
{
public BcelShadow(BcelWorld world, Kind kind, Member signature, LazyMethodGen enclosingMethod, BcelShadow enclosingShadow) {
super(kind, signature, enclosingShadow);
this.world = world;
this.enclosingMethod = enclosingMethod;
// fallsThrough = kind.argsOnStack();
}

// ---- copies all state, including Shadow's mungers...
@@ -192,23 +170,21 @@ public class BcelShadow extends Shadow {
return world;
}



private void deleteNewAndDup() {
final ConstantPoolGen cpg = getEnclosingClass().getConstantPoolGen();
final ConstantPool cpg = getEnclosingClass().getConstantPool();
int depth = 1;
InstructionHandle ih = range.getStart();

// Go back from where we are looking for 'NEW' that takes us to a stack depth of 0. INVOKESPECIAL <init>
while (true) {
Instruction inst = ih.getInstruction();
if (inst instanceof INVOKESPECIAL
&& ((INVOKESPECIAL) inst).getName(cpg).equals("<init>")) {
if (inst.opcode==Constants.INVOKESPECIAL
&& ((InvokeInstruction) inst).getName(cpg).equals("<init>")) {
depth++;
} else if (inst instanceof NEW) {
} else if (inst.opcode==Constants.NEW) {
depth--;
if (depth == 0) break;
} else if (inst instanceof DUP_X2) {
} else if (inst.opcode==Constants.DUP_X2) {
// This code seen in the wild (by Brad):
// 40: new #12; //class java/lang/StringBuffer
// STACK: STRINGBUFFER
@@ -243,7 +219,6 @@ public class BcelShadow extends Shadow {
// bytecode sequence has only been seen once in the wild.
ih.setInstruction(InstructionConstants.DUP);
}
ih = ih.getPrev();
}
// now IH points to the NEW. We're followed by the DUP, and that is followed
@@ -251,17 +226,15 @@ public class BcelShadow extends Shadow {
InstructionHandle newHandle = ih;
InstructionHandle endHandle = newHandle.getNext();
InstructionHandle nextHandle;
//
if (endHandle.getInstruction() instanceof DUP) {
if (endHandle.getInstruction().opcode==Constants.DUP) {
nextHandle = endHandle.getNext();
retargetFrom(newHandle, nextHandle);
retargetFrom(endHandle, nextHandle);
} else if (endHandle.getInstruction() instanceof DUP_X1) {
} else if (endHandle.getInstruction().opcode==Constants.DUP_X1) {
InstructionHandle dupHandle = endHandle;
endHandle = endHandle.getNext();
nextHandle = endHandle.getNext();
if (endHandle.getInstruction() instanceof SWAP) {}
if (endHandle.getInstruction().opcode==Constants.SWAP) {}
else {
// XXX see next XXX comment
throw new RuntimeException("Unhandled kind of new " + endHandle);
@@ -532,7 +505,7 @@ public class BcelShadow extends Shadow {
if (clinitStart.getInstruction() instanceof InvokeInstruction) {
InvokeInstruction ii = (InvokeInstruction)clinitStart.getInstruction();
if (ii
.getName(enclosingMethod.getEnclosingClass().getConstantPoolGen())
.getName(enclosingMethod.getEnclosingClass().getConstantPool())
.equals(NameMangler.AJC_PRE_CLINIT_NAME)) {
clinitStart = clinitStart.getNext();
}
@@ -543,7 +516,7 @@ public class BcelShadow extends Shadow {
//XXX should move the end before the postClinit, but the return is then tricky...
// if (clinitEnd.getInstruction() instanceof InvokeInstruction) {
// InvokeInstruction ii = (InvokeInstruction)clinitEnd.getInstruction();
// if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPoolGen()).equals(NameMangler.AJC_POST_CLINIT_NAME)) {
// if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPool()).equals(NameMangler.AJC_POST_CLINIT_NAME)) {
// clinitEnd = clinitEnd.getPrev();
// }
// }
@@ -602,10 +575,10 @@ public class BcelShadow extends Shadow {
}
private static String findHandlerParamName(InstructionHandle startOfHandler) {
if (startOfHandler.getInstruction() instanceof StoreInstruction &&
if (startOfHandler.getInstruction().isStoreInstruction() &&
startOfHandler.getNext() != null)
{
int slot = ((StoreInstruction)startOfHandler.getInstruction()).getIndex();
int slot = startOfHandler.getInstruction().getIndex();
//System.out.println("got store: " + startOfHandler.getInstruction() + ", " + index);
InstructionTargeter[] targeters = startOfHandler.getNext().getTargeters();
if (targeters!=null) {
@@ -1024,7 +997,7 @@ public class BcelShadow extends Shadow {
if (sources != null) {
for (int i = sources.length - 1; i >= 0; i--) {
InstructionTargeter source = sources[i];
if (source instanceof BranchInstruction) {
if (source instanceof InstructionBranch) {
source.updateTarget(from, to);
}
}
@@ -1259,12 +1232,12 @@ public class BcelShadow extends Shadow {
if (hasThis()) {
((BcelVar)getThisVar()).appendLoad(il, fact);
} else {
il.append(new ACONST_NULL());
il.append(InstructionConstants.ACONST_NULL);
}
if (hasTarget()) {
((BcelVar)getTargetVar()).appendLoad(il, fact);
} else {
il.append(new ACONST_NULL());
il.append(InstructionConstants.ACONST_NULL);
}
switch(getArgCount()) {
@@ -1437,34 +1410,32 @@ public class BcelShadow extends Shadow {
// Lets go back through the code from the start of the shadow
InstructionHandle searchPtr = range.getStart().getPrev();
while (Range.isRangeHandle(searchPtr) ||
searchPtr.getInstruction() instanceof StoreInstruction) { // ignore this instruction - it doesnt give us the info we want
searchPtr.getInstruction().isStoreInstruction()) { // ignore this instruction - it doesnt give us the info we want
searchPtr = searchPtr.getPrev();
}
// A load instruction may tell us the real type of what the clone() call is on
if (searchPtr.getInstruction() instanceof LoadInstruction) {
LoadInstruction li = (LoadInstruction)searchPtr.getInstruction();
li.getIndex();
LocalVariableTag lvt = LazyMethodGen.getLocalVariableTag(searchPtr,li.getIndex());
if (searchPtr.getInstruction().isLoadInstruction()) {
LocalVariableTag lvt = LazyMethodGen.getLocalVariableTag(searchPtr,searchPtr.getInstruction().getIndex());
if (lvt!=null) return UnresolvedType.forSignature(lvt.getType());
}
// A field access instruction may tell us the real type of what the clone() call is on
if (searchPtr.getInstruction() instanceof FieldInstruction) {
FieldInstruction si = (FieldInstruction)searchPtr.getInstruction();
Type t = si.getFieldType(getEnclosingClass().getConstantPoolGen());
Type t = si.getFieldType(getEnclosingClass().getConstantPool());
return BcelWorld.fromBcel(t);
}
// A new array instruction obviously tells us it is an array type !
if (searchPtr.getInstruction() instanceof ANEWARRAY) {
if (searchPtr.getInstruction().opcode==Constants.ANEWARRAY) {
//ANEWARRAY ana = (ANEWARRAY)searchPoint.getInstruction();
//Type t = ana.getType(getEnclosingClass().getConstantPoolGen());
// Type t = ana.getType(getEnclosingClass().getConstantPool());
// Just use a standard java.lang.object array - that will work fine
return BcelWorld.fromBcel(new ArrayType(Type.OBJECT,1));
}
// A multi new array instruction obviously tells us it is an array type !
if (searchPtr.getInstruction() instanceof MULTIANEWARRAY) {
MULTIANEWARRAY ana = (MULTIANEWARRAY)searchPtr.getInstruction();
// Type t = ana.getType(getEnclosingClass().getConstantPoolGen());
// Type t = ana.getType(getEnclosingClass().getConstantPool());
// t = new ArrayType(t,ana.getDimensions());
// Just use a standard java.lang.object array - that will work fine
return BcelWorld.fromBcel(new ArrayType(Type.OBJECT,ana.getDimensions()));
@@ -1628,7 +1599,7 @@ public class BcelShadow extends Shadow {
// by determining what "kind" of shadow we are, we can find out the
// annotations on the appropriate element (method, field, constructor, type).
// Then create one BcelVar entry in the map for each annotation, keyed by
// annotation type (UnresolvedType).
// annotation type.
// FIXME asc Refactor this code, there is duplication
ResolvedType[] annotations = null;
@@ -1827,7 +1798,7 @@ public class BcelShadow extends Shadow {
private List findReturnInstructions() {
List returns = new ArrayList();
for (InstructionHandle ih = range.getStart(); ih != range.getEnd(); ih = ih.getNext()) {
if (ih.getInstruction() instanceof ReturnInstruction) {
if (ih.getInstruction().isReturnInstruction()) {
returns.add(ih);
}
}
@@ -1861,7 +1832,7 @@ public class BcelShadow extends Shadow {
int i=returns.size()-1;
while (newReturnInstruction == null && i>=0) {
InstructionHandle ih = (InstructionHandle)returns.get(i);
if (!(ih.getInstruction() instanceof RETURN)) {
if (ih.getInstruction().opcode!=Constants.RETURN) {
newReturnInstruction = Utility.copyInstruction(ih.getInstruction());
}
i--;
@@ -1984,7 +1955,7 @@ public class BcelShadow extends Shadow {
InstructionList ih = new InstructionList(InstructionConstants.NOP);
handler.append(exceptionVar.createLoad(fact));
handler.append(fact.createInstanceOf(eiieBcelType));
BranchInstruction bi =
InstructionBranch bi =
InstructionFactory.createBranchInstruction(Constants.IFEQ,ih.getStart());
handler.append(bi);
handler.append(exceptionVar.createLoad(fact));
@@ -2105,7 +2076,7 @@ public class BcelShadow extends Shadow {
String aspectname = munger.getConcreteAspect().getName();
String ptwField = NameMangler.perTypeWithinFieldForTarget(munger.getConcreteAspect());
entrySuccessInstructions.append(new PUSH(fact.getConstantPool(),t.getName()));
entrySuccessInstructions.append(InstructionFactory.PUSH(fact.getConstantPool(),t.getName()));
entrySuccessInstructions.append(fact.createInvoke(aspectname,"ajc$createAspectInstance",new ObjectType(aspectname),
new Type[]{new ObjectType("java.lang.String")},Constants.INVOKESTATIC));
@@ -2315,7 +2286,7 @@ public class BcelShadow extends Shadow {
boolean canSeeProceedPassedToOther = false;
InstructionHandle curr = adviceMethod.getBody().getStart();
InstructionHandle end = adviceMethod.getBody().getEnd();
ConstantPoolGen cpg = adviceMethod.getEnclosingClass().getConstantPoolGen();
ConstantPool cpg = adviceMethod.getEnclosingClass().getConstantPool();
while (curr != end) {
InstructionHandle next = curr.getNext();
Instruction inst = curr.getInstruction();
@@ -2538,12 +2509,12 @@ public class BcelShadow extends Shadow {

InstructionHandle curr = localAdviceMethod.getBody().getStart();
InstructionHandle end = localAdviceMethod.getBody().getEnd();
ConstantPoolGen cpg = localAdviceMethod.getEnclosingClass().getConstantPoolGen();
ConstantPool cpg = localAdviceMethod.getEnclosingClass().getConstantPool();
while (curr != end) {
InstructionHandle next = curr.getNext();
Instruction inst = curr.getInstruction();
if ((inst instanceof INVOKESTATIC)
&& proceedName.equals(((INVOKESTATIC) inst).getMethodName(cpg))) {
if ((inst.opcode==Constants.INVOKESTATIC)
&& proceedName.equals(((InvokeInstruction) inst).getMethodName(cpg))) {

localAdviceMethod.getBody().append(
curr,
@@ -2563,7 +2534,7 @@ public class BcelShadow extends Shadow {
// [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();
ConstantPool cpg = localAdviceMethod.getEnclosingClass().getConstantPool();
while (curr != end) {
InstructionHandle next = curr.getNext();
Instruction inst = curr.getInstruction();
@@ -2753,7 +2724,7 @@ public class BcelShadow extends Shadow {
indexIntoObjectArrayForArguments=1;
} else {
// use local variable 0 (which is 'this' for a non-static method)
ret.append(new ALOAD(0));
ret.append(InstructionFactory.createALOAD(0));
indexIntoCallbackMethodForArguments++;
}
}
@@ -2791,7 +2762,7 @@ public class BcelShadow extends Shadow {
Type stateType = callbackMethod.getArgumentTypes()[i];
BcelWorld.fromBcel(stateType).resolve(world);
if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
ret.append(new ALOAD(localJp));// from localAdvice signature
ret.append(new InstructionLV(Constants.ALOAD,localJp));// from localAdvice signature
} else {
ret.append(InstructionFactory.createLoad(objectArrayType, localProceedArgArray));
ret.append(Utility.createConstant(fact, i-indexIntoCallbackMethodForArguments +indexIntoObjectArrayForArguments));
@@ -2814,7 +2785,7 @@ public class BcelShadow extends Shadow {
/*ResolvedType stateTypeX =*/
BcelWorld.fromBcel(stateType).resolve(world);
if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
ret.append(new ALOAD(localJp));// from localAdvice signature
ret.append(InstructionFactory.createALOAD(localJp));// from localAdvice signature
// } else if ("Lorg/aspectj/lang/ProceedingJoinPoint;".equals(stateType.getSignature())) {
// //FIXME ALEX?
// ret.append(new ALOAD(localJp));// from localAdvice signature
@@ -3089,7 +3060,7 @@ public class BcelShadow extends Shadow {
if (munger.getConcreteAspect()!=null && munger.getConcreteAspect().isAnnotationStyleAspect()
&& munger.getDeclaringAspect()!=null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
// stick the bitflags on the stack and call the variant of linkClosureAndJoinPoint that takes an int
closureInstantiation.append(fact.createConstant(new Integer(bitflags)));
closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags)));
closureInstantiation.append(Utility.createInvoke(
getFactory(),
getWorld(),
@@ -3195,7 +3166,7 @@ public class BcelShadow extends Shadow {
stateIndex++;
}
il.append(fact.createNew(new ObjectType(constructor.getDeclaringType().getName())));
il.append(new DUP());
il.append(InstructionConstants.DUP);
arrayVar.appendLoad(il, fact);
il.append(Utility.createInvoke(fact, world, constructor));
if (getKind() == PreInitialization) {
@@ -3246,7 +3217,7 @@ public class BcelShadow extends Shadow {
Modifier.PUBLIC,
new String[] {},
getWorld());
InstructionFactory fact = new InstructionFactory(closureClass.getConstantPoolGen());
InstructionFactory fact = new InstructionFactory(closureClass.getConstantPool());
// constructor
LazyMethodGen constructor = new LazyMethodGen(Modifier.PUBLIC,
@@ -3393,7 +3364,7 @@ public class BcelShadow extends Shadow {
InvokeInstruction superCallInstruction =
(InvokeInstruction) superCallHandle.getInstruction();
return superCallInstruction.getArgumentTypes(
getEnclosingClass().getConstantPoolGen());
getEnclosingClass().getConstantPool());
}



+ 35
- 34
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java View File

@@ -21,17 +21,16 @@ import java.util.Map;
import java.util.Set;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.generic.BranchInstruction;
import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.apache.bcel.generic.FieldGen;
import org.aspectj.apache.bcel.generic.INVOKESPECIAL;
import org.aspectj.apache.bcel.generic.InstructionBranch;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InvokeInstruction;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.asm.AsmManager;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
@@ -67,6 +66,7 @@ import org.aspectj.weaver.World;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.Pointcut;


//XXX addLazyMethodGen is probably bad everywhere
public class BcelTypeMunger extends ConcreteTypeMunger {

@@ -412,9 +412,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
InstructionList insList = aMethod.getBody();
InstructionHandle handle = insList.getStart();
while (handle!= null) {
if (handle.getInstruction() instanceof INVOKESPECIAL) {
ConstantPoolGen cpg = newParentTarget.getConstantPoolGen();
INVOKESPECIAL invokeSpecial = (INVOKESPECIAL)handle.getInstruction();
if (handle.getInstruction().opcode==Constants.INVOKESPECIAL) {
ConstantPool cpg = newParentTarget.getConstantPool();
InvokeInstruction invokeSpecial = (InvokeInstruction)handle.getInstruction();
if (invokeSpecial.getClassName(cpg).equals(currentParent) && invokeSpecial.getMethodName(cpg).equals("<init>")) {
// System.err.println("Transforming super call '<init>"+sp.getSignature(cpg)+"'");
@@ -458,7 +458,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
/**
* Creates a nice signature for the ctor, something like "(int,Integer,String)"
*/
private String createReadableCtorSig(ResolvedType newParent, ConstantPoolGen cpg, INVOKESPECIAL invokeSpecial) {
private String createReadableCtorSig(ResolvedType newParent, ConstantPool cpg, InvokeInstruction invokeSpecial) {
StringBuffer sb = new StringBuffer();
Type[] ctorArgs = invokeSpecial.getArgumentTypes(cpg);
sb.append(newParent.getClassName());
@@ -523,7 +523,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
return true;
//throw new BCException("no match for " + member + " in " + gen);
} else if (member.getKind() == Member.STATIC_INITIALIZATION) {
return gen.forcePublic();
gen.forcePublic();
return true;
} else {
throw new RuntimeException("unimplemented");
}
@@ -639,7 +640,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
member.getModifiers(),
BcelWorld.makeBcelType(member.getReturnType()),
member.getName(),
gen.getConstantPoolGen());
gen.getConstantPool());
}


@@ -656,7 +657,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
FieldGen fg = makeFieldGen(gen,
AjcMemberMaker.perObjectField(gen.getType(), aspectType));

gen.addField(fg.getField(),getSourceLocation());
gen.addField(fg,getSourceLocation());
Type fieldType = BcelWorld.makeBcelType(aspectType);
@@ -714,7 +715,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
// Add (to the target type) the field that will hold the aspect instance
// e.g ajc$com_blah_SecurityAspect$ptwAspectInstance
FieldGen fg = makeFieldGen(gen, AjcMemberMaker.perTypeWithinField(gen.getType(), aspectType));
gen.addField(fg.getField(),getSourceLocation());
gen.addField(fg,getSourceLocation());
// Add an accessor for this new field, the ajc$<aspectname>$localAspectOf() method
// e.g. "public com_blah_SecurityAspect ajc$com_blah_SecurityAspect$localAspectOf()"
@@ -808,9 +809,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
if (annotationsOnRealMember!=null) {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationX annotationX = annotationsOnRealMember[i];
Annotation a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
newMethod.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
AnnotationGen a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true);
newMethod.addAnnotation(new AnnotationX(ag,weaver.getWorld()));
}
}
// the below loop fixes the very special (and very stupid)
@@ -903,9 +904,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
if (annotationsOnRealMember!=null) {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationX annotationX = annotationsOnRealMember[i];
Annotation a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
AnnotationGen a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true);
mg.addAnnotation(new AnnotationX(ag,weaver.getWorld()));
}
}
}
@@ -1179,9 +1180,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
if (annotationsOnRealMember!=null) {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationX annotationX = annotationsOnRealMember[i];
Annotation a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
AnnotationGen a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true);
mg.addAnnotation(new AnnotationX(ag,weaver.getWorld()));
}
}
}
@@ -1192,7 +1193,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
// getfield
body.append(InstructionConstants.ALOAD_0);
body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType())));
BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null);
body.append(ifNonNull);
// Create and store a new instance
@@ -1247,7 +1248,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
aspectType);
weaver.getLazyClassGen().addField(makeFieldGen(
weaver.getLazyClassGen(),
host).getField(), null);
host), null);
return true;
}

@@ -1387,9 +1388,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
if (annotationsOnRealMember!=null) {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationX annotationX = annotationsOnRealMember[i];
Annotation a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
AnnotationGen a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true);
mg.addAnnotation(new AnnotationX(ag,weaver.getWorld()));
}
}
// the below loop fixes the very special (and very stupid)
@@ -1578,13 +1579,13 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
if (annotationsOnRealMember!=null) {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationX annotationX = annotationsOnRealMember[i];
Annotation a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
AnnotationGen a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true);
fg.addAnnotation(ag);
}
}
gen.addField(fg.getField(),getSourceLocation());
gen.addField(fg,getSourceLocation());
}
return true;
@@ -1602,13 +1603,13 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
if (annotationsOnRealMember!=null) {
for (int i = 0; i < annotationsOnRealMember.length; i++) {
AnnotationX annotationX = annotationsOnRealMember[i];
Annotation a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
AnnotationGen a = annotationX.getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true);
fg.addAnnotation(ag);
}
}
gen.addField(fg.getField(),getSourceLocation());
gen.addField(fg,getSourceLocation());
//this uses a shadow munger to add init method to constructors
//weaver.getShadowMungers().add(makeInitCallShadowMunger(initMethod));
@@ -1716,7 +1717,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
public ConcreteTypeMunger parameterizedFor(ResolvedType target) {
return new BcelTypeMunger(munger.parameterizedFor(target),aspectType);
}
public ConcreteTypeMunger parameterizeWith(Map m, World w) {
return new BcelTypeMunger(munger.parameterizeWith(m,w),aspectType);
}

+ 1
- 1
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java View File

@@ -82,7 +82,6 @@ import org.aspectj.weaver.World;
import org.aspectj.weaver.patterns.AndPointcut;
import org.aspectj.weaver.patterns.BindingAnnotationTypePattern;
import org.aspectj.weaver.patterns.BindingTypePattern;
import org.aspectj.weaver.patterns.CflowPointcut;
import org.aspectj.weaver.patterns.ConcreteCflowPointcut;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.DeclareParents;
@@ -476,6 +475,7 @@ public class BcelWeaver implements IWeaver {
if (trace.isTraceEnabled()) trace.enter("prepareForWeave",this);
needToReweaveWorld = xcutSet.hasChangedSinceLastReset();

// update mungers
for (Iterator i = addedClasses.iterator(); i.hasNext(); ) {
UnwovenClassFile jc = (UnwovenClassFile)i.next();

+ 22
- 32
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java View File

@@ -24,27 +24,20 @@ import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.ClassParser;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.ConstantPool;
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.ConstantPoolGen;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.generic.FieldInstruction;
import org.aspectj.apache.bcel.generic.GETSTATIC;
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;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InvokeInstruction;
import org.aspectj.apache.bcel.generic.MONITORENTER;
import org.aspectj.apache.bcel.generic.MONITOREXIT;
import org.aspectj.apache.bcel.generic.MULTIANEWARRAY;
import org.aspectj.apache.bcel.generic.NEWARRAY;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.PUTSTATIC;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.apache.bcel.util.ClassLoaderReference;
import org.aspectj.apache.bcel.util.ClassLoaderRepository;
@@ -60,6 +53,7 @@ import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.ICrossReferenceHandler;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.MemberImpl;
import org.aspectj.weaver.NewParentTypeMunger;
@@ -113,9 +107,6 @@ public class BcelWorld extends World implements Repository {
}

private static List getPathEntries(String s) {
List ret = new ArrayList();
StringTokenizer tok = new StringTokenizer(s, File.pathSeparator);
@@ -145,7 +136,7 @@ public class BcelWorld extends World implements Repository {
// TODO Alex do we need to call org.aspectj.apache.bcel.Repository.setRepository(delegate);
// if so, how can that be safe in J2EE ?? (static stuff in Bcel)
}
/**
* Build a World from a ClassLoader, for LTW support
*
@@ -439,11 +430,11 @@ public class BcelWorld extends World implements Repository {
}

public static Member makeFieldJoinPointSignature(LazyClassGen cg, FieldInstruction fi) {
ConstantPoolGen cpg = cg.getConstantPoolGen();
ConstantPool cpg = cg.getConstantPool();
return
MemberImpl.field(
fi.getClassName(cpg),
(fi instanceof GETSTATIC || fi instanceof PUTSTATIC)
(fi.opcode==Constants.GETSTATIC || fi.opcode==Constants.PUTSTATIC)
? Modifier.STATIC: 0,
fi.getName(cpg),
fi.getSignature(cpg));
@@ -466,7 +457,7 @@ public class BcelWorld extends World implements Repository {
}

public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberImpl.Kind kind) {
public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberKind kind) {
Member ret = mg.getMemberView();
if (ret == null) {
int mods = mg.getAccessFlags();
@@ -474,6 +465,7 @@ public class BcelWorld extends World implements Repository {
mods |= Modifier.INTERFACE;
}
if (kind == null) {
//OPTIMIZE surely we can pass the kind in and not resort to string compares?
if (mg.getName().equals("<init>")) {
kind = Member.CONSTRUCTOR;
} else if (mg.getName().equals("<clinit>")) {
@@ -496,23 +488,21 @@ public class BcelWorld extends World implements Repository {
}
public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg,InstructionHandle h) {
MONITORENTER i = (MONITORENTER)h.getInstruction();
return MemberImpl.monitorEnter();
}

public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg,InstructionHandle h) {
MONITOREXIT i = (MONITOREXIT)h.getInstruction();
return MemberImpl.monitorExit();
}
public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg, InstructionHandle handle) {
Instruction i = handle.getInstruction();
ConstantPoolGen cpg = cg.getConstantPoolGen();
ConstantPool cpg = cg.getConstantPool();
Member retval = null;

if (i instanceof ANEWARRAY) {
ANEWARRAY arrayInstruction = (ANEWARRAY)i;
Type ot = arrayInstruction.getType(cpg);
if (i.opcode==Constants.ANEWARRAY) {
// ANEWARRAY arrayInstruction = (ANEWARRAY)i;
Type ot = i.getType(cpg);
UnresolvedType ut = fromBcel(ot);
ut = UnresolvedType.makeArray(ut,1);
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", new ResolvedType[]{ResolvedType.INT});
@@ -532,9 +522,9 @@ public class BcelWorld extends World implements Repository {
for (int ii=0;ii<dimensions;ii++) parms[ii] = ResolvedType.INT;
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", parms);
} else if (i instanceof NEWARRAY) {
NEWARRAY arrayInstruction = (NEWARRAY)i;
Type ot = arrayInstruction.getType();
} else if (i.opcode==Constants.NEWARRAY) {
// NEWARRAY arrayInstruction = (NEWARRAY)i;
Type ot = i.getType();
UnresolvedType ut = fromBcel(ot);
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", new ResolvedType[]{ResolvedType.INT});
} else {
@@ -544,7 +534,7 @@ public class BcelWorld extends World implements Repository {
}

public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, InvokeInstruction ii) {
ConstantPoolGen cpg = cg.getConstantPoolGen();
ConstantPool cpg = cg.getConstantPool();
String name = ii.getName(cpg);
String declaring = ii.getClassName(cpg);
UnresolvedType declaringType = null;
@@ -554,16 +544,16 @@ public class BcelWorld extends World implements Repository {
int modifier =
(ii instanceof INVOKEINTERFACE)
? Modifier.INTERFACE
: (ii instanceof INVOKESTATIC)
: (ii.opcode==Constants.INVOKESTATIC)
? Modifier.STATIC
: (ii instanceof INVOKESPECIAL && ! name.equals("<init>"))
: (ii.opcode==Constants.INVOKESPECIAL && ! name.equals("<init>"))
? Modifier.PRIVATE
: 0;

// in Java 1.4 and after, static method call of super class within subclass method appears
// as declared by the subclass in the bytecode - but they are not
// see #104212
if (ii instanceof INVOKESTATIC) {
if (ii.opcode==Constants.INVOKESTATIC) {
ResolvedType appearsDeclaredBy = resolve(declaring);
// look for the method there
for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator.hasNext();) {
@@ -724,13 +714,13 @@ public class BcelWorld extends World implements Repository {
if (!jc.isClass()) {
return false;
}
Annotation anns[] = jc.getAnnotations();
AnnotationGen anns[] = jc.getAnnotations();
if (anns.length == 0) {
return false;
}
boolean couldBeAtAspectJStyle = false;
for (int i = 0; i < anns.length; i++) {
Annotation ann = anns[i];
AnnotationGen ann = anns[i];
if ("Lorg/aspectj/lang/annotation/Aspect;".equals(ann.getTypeSignature())) {
couldBeAtAspectJStyle = true;
}

+ 160
- 148
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java View File

@@ -32,27 +32,23 @@ import java.util.TreeMap;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.ConstantUtf8;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Signature;
import org.aspectj.apache.bcel.classfile.Synthetic;
import org.aspectj.apache.bcel.classfile.Unknown;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.generic.BasicType;
import org.aspectj.apache.bcel.generic.ClassGen;
import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.apache.bcel.generic.FieldGen;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.PUSH;
import org.aspectj.apache.bcel.generic.RETURN;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.SourceLocation;
@@ -72,6 +68,7 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.UnresolvedType.TypeKind;



/**
* Lazy lazy lazy.
* We don't unpack the underlying class unless necessary. Things
@@ -93,10 +90,11 @@ public final class LazyClassGen {
private BcelObjectType myType; // XXX is not set for types we create
private ClassGen myGen;
private ConstantPoolGen constantPoolGen;
private ConstantPool constantPoolGen;
private World world;
private String packageName = null;

private List /*BcelField*/ fields = new ArrayList();
private List /*LazyMethodGen*/ methodGens = new ArrayList();
private List /*LazyClassGen*/ classGens = new ArrayList();
private List /*AnnotationGen*/ annotations = new ArrayList();
@@ -157,7 +155,7 @@ public final class LazyClassGen {
byte[] bytes = Utility.stringToUTF(data);
int length = bytes.length;

return new Unknown(nameIndex, length, bytes, constantPoolGen.getConstantPool());
return new Unknown(nameIndex, length, bytes, constantPoolGen);
}

// private LazyClassGen() {}
@@ -292,9 +290,9 @@ public final class LazyClassGen {
// Do we need to calculate an SUID and add it?
if (!hasSerialVersionUIDField && world.isAddSerialVerUID()) {
calculatedSerialVersionUID = myGen.getSUID();
Field fg = new FieldGen(
FieldGen fg = new FieldGen(
Constants.ACC_PRIVATE|Constants.ACC_FINAL|Constants.ACC_STATIC,
BasicType.LONG,"serialVersionUID",getConstantPoolGen()).getField();
BasicType.LONG,"serialVersionUID",getConstantPool());
addField(fg);
hasSerialVersionUIDField=true;
serialVersionUIDRequiresInitialization=true;
@@ -305,11 +303,15 @@ public final class LazyClassGen {
}
}

Method[] methods = myGen.getMethods();
Method[] methods = myGen.getMethods();
for (int i = 0; i < methods.length; i++) {
addMethodGen(new LazyMethodGen(methods[i], this));
}

ResolvedMember[] fields = myType.getDeclaredFields();
for (int i=0; i<fields.length; i++) {
this.fields.add((BcelField)fields[i]);
}
}

public static boolean hasSerialVersionUIDField (ResolvedType type) {
@@ -333,9 +335,10 @@ public final class LazyClassGen {
// ----

public String getInternalClassName() {
return getConstantPoolGen().getConstantPool().getConstantString(
myGen.getClassNameIndex(),
Constants.CONSTANT_Class);
return getConstantPool().getConstantString_CONSTANTClass(myGen.getClassNameIndex());
//getConstantPool().getConstantString(
// myGen.getClassNameIndex(),
// Constants.CONSTANT_Class);

}

@@ -384,7 +387,7 @@ public final class LazyClassGen {
methodGens.add(gen);
if (highestLineNumber < gen.highestLineNumber) highestLineNumber = gen.highestLineNumber;
}
public void addMethodGen(LazyMethodGen gen, ISourceLocation sourceLocation) {
addMethodGen(gen);
if (!gen.getMethod().isPrivate()) {
@@ -393,7 +396,7 @@ public final class LazyClassGen {
}

public void errorOnAddedField (Field field, ISourceLocation sourceLocation) {
public void errorOnAddedField (FieldGen field, ISourceLocation sourceLocation) {
if (isSerializable && !hasSerialVersionUIDField) {
getWorld().getLint().serialVersionUIDBroken.signal(
new String[] {
@@ -438,20 +441,20 @@ public final class LazyClassGen {
return methodGens; //???Collections.unmodifiableList(methodGens);
}
// FIXME asc Should be collection returned here
public Field[] getFieldGens() {
return myGen.getFields();
public List/*BcelField*/ getFieldGens() {
return fields;
// return myGen.getFields();
}
public Field getField(String name) {
Field[] allFields = myGen.getFields();
if (allFields==null) return null;
for (int i = 0; i < allFields.length; i++) {
Field field = allFields[i];
if (field.getName().equals(name)) return field;
}
return null;
}
// public Field getField(String name) {
// Field[] allFields = myGen.getFields();
// if (allFields==null) return null;
// for (int i = 0; i < allFields.length; i++) {
// Field field = allFields[i];
// if (field.getName().equals(name)) return field;
// }
// return null;
// }
// FIXME asc How do the ones on the underlying class surface if this just returns new ones added?
// FIXME asc ...although no one calls this right now !
@@ -460,7 +463,7 @@ public final class LazyClassGen {
}

private void writeBack(BcelWorld world) {
if (getConstantPoolGen().getSize() > Short.MAX_VALUE) {
if (getConstantPool().getSize() > Short.MAX_VALUE) {
reportClassTooBigProblem();
return;
}
@@ -470,7 +473,7 @@ public final class LazyClassGen {
AnnotationGen element = (AnnotationGen) iter.next();
myGen.addAnnotation(element);
}
// Attribute[] annAttributes = org.aspectj.apache.bcel.classfile.Utility.getAnnotationAttributes(getConstantPoolGen(),annotations);
// Attribute[] annAttributes = org.aspectj.apache.bcel.classfile.Utility.getAnnotationAttributes(getConstantPool(),annotations);
// for (int i = 0; i < annAttributes.length; i++) {
// Attribute attribute = annAttributes[i];
// System.err.println("Adding attribute for "+attribute);
@@ -479,19 +482,14 @@ public final class LazyClassGen {
}
// Add a weaver version attribute to the file being produced (if necessary...)
boolean hasVersionAttribute = false;
Attribute[] attrs = myGen.getAttributes();
for (int i = 0; i < attrs.length && !hasVersionAttribute; i++) {
Attribute attribute = attrs[i];
if (attribute.getName().equals("org.aspectj.weaver.WeaverVersion")) hasVersionAttribute=true;
}
if (!hasVersionAttribute)
myGen.addAttribute(BcelAttributes.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPoolGen()));
if (!myGen.hasAttribute("org.aspectj.weaver.WeaverVersion")) {
myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPool()));
}

if (myType != null && myType.getWeaverState() != null) {
myGen.addAttribute(BcelAttributes.bcelAttribute(
myGen.addAttribute(Utility.bcelAttribute(
new AjAttribute.WeaverState(myType.getWeaverState()),
getConstantPoolGen()));
getConstantPool()));
}

//FIXME ATAJ needed only for slow Aspects.aspectOf() - keep or remove
@@ -502,29 +500,43 @@ public final class LazyClassGen {
// }

addAjcInitializers();

// 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430). Will be revisited when contents
// of attribute are confirmed to be correct.
boolean sourceDebugExtensionSupportSwitchedOn = false;
int len = methodGens.size();
myGen.setMethods(new Method[0]);
if (sourceDebugExtensionSupportSwitchedOn) {
calculateSourceDebugExtensionOffsets();
}
calculateSourceDebugExtensionOffsets();
int len = methodGens.size();
myGen.setMethods(Method.NoMethods);
for (int i = 0; i < len; i++) {
LazyMethodGen gen = (LazyMethodGen) methodGens.get(i);
// we skip empty clinits
if (isEmptyClinit(gen)) continue;
myGen.addMethod(gen.getMethod());
}
if (inlinedFiles.size() != 0) {
if (hasSourceDebugExtensionAttribute(myGen)) {
world.showMessage(
IMessage.WARNING,
WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()),
null,
null);
len = fields.size();
myGen.setFields(Field.NoFields);
for (int i = 0; i < len; i++) {
BcelField gen = (BcelField) fields.get(i);
myGen.addField(gen.getField(this.constantPoolGen));
}

if (sourceDebugExtensionSupportSwitchedOn) {
if (inlinedFiles.size() != 0) {
if (hasSourceDebugExtensionAttribute(myGen)) {
world.showMessage(
IMessage.WARNING,
WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()),
null,
null);
}
// myGen.addAttribute(getSourceDebugExtensionAttribute());
}
// 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430). Will be revisited when contents
// of attribute are confirmed to be correct.
// myGen.addAttribute(getSourceDebugExtensionAttribute());
}
}
fixupGenericSignatureAttribute();
}
@@ -551,11 +563,7 @@ public final class LazyClassGen {
// 2. Find the old attribute
Signature sigAttr = null;
if (myType!=null) { // if null, this is a type built from scratch, it won't already have a sig attribute
Attribute[] as = myGen.getAttributes();
for (int i = 0; i < as.length; i++) {
Attribute attribute = as[i];
if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute;
}
sigAttr = (Signature) myGen.getAttribute("Signature");
}
// 3. Do we need an attribute?
@@ -610,7 +618,7 @@ public final class LazyClassGen {
private Signature createSignatureAttribute(String signature) {
int nameIndex = constantPoolGen.addUtf8("Signature");
int sigIndex = constantPoolGen.addUtf8(signature);
return new Signature(nameIndex,2,sigIndex,constantPoolGen.getConstantPool());
return new Signature(nameIndex,2,sigIndex,constantPoolGen);
}

/**
@@ -623,7 +631,7 @@ public final class LazyClassGen {
// create an empty myGen so that we can give back a return value that doesn't upset the
// rest of the process.
myGen = new ClassGen(myGen.getClassName(), myGen.getSuperclassName(),
myGen.getFileName(), myGen.getAccessFlags(), myGen.getInterfaceNames());
myGen.getFileName(), myGen.getModifiers(), myGen.getInterfaceNames());
// raise an error against this compilation unit.
getWorld().showMessage(
IMessage.ERROR,
@@ -634,15 +642,16 @@ public final class LazyClassGen {
}

private static boolean hasSourceDebugExtensionAttribute(ClassGen gen) {
ConstantPoolGen pool = gen.getConstantPool();
Attribute[] attrs = gen.getAttributes();
for (int i = 0; i < attrs.length; i++) {
if ("SourceDebugExtension"
.equals(((ConstantUtf8) pool.getConstant(attrs[i].getNameIndex())).getBytes())) {
return true;
}
}
return false;
return gen.hasAttribute("SourceDebugExtension");
// ConstantPool pool = gen.getConstantPool();
// Attribute[] attrs = gen.getAttributes();
// for (int i = 0; i < attrs.length; i++) {
// if ("SourceDebugExtension"
// .equals(((ConstantUtf8) pool.getConstant(attrs[i].getNameIndex())).getBytes())) {
// return true;
// }
// }
// return false;
}

public JavaClass getJavaClass(BcelWorld world) {
@@ -725,10 +734,10 @@ public final class LazyClassGen {

public String toShortString() {
String s =
org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getAccessFlags(), true);
org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getModifiers(), true);
if (s != "")
s += " ";
s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getAccessFlags());
s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getModifiers());
s += " ";
s += myGen.getClassName();
return s;
@@ -798,7 +807,7 @@ public final class LazyClassGen {
//System.err.println("checking clinig: " + gen);
InstructionHandle start = gen.getBody().getStart();
while (start != null) {
if (Range.isRangeHandle(start) || (start.getInstruction() instanceof RETURN)) {
if (Range.isRangeHandle(start) || (start.getInstruction().opcode==Constants.RETURN)) {
start = start.getNext();
} else {
return false;
@@ -808,7 +817,7 @@ public final class LazyClassGen {
return true;
}

public ConstantPoolGen getConstantPoolGen() {
public ConstantPool getConstantPool() {
return constantPoolGen;
}
@@ -931,8 +940,9 @@ public final class LazyClassGen {
} else {
jpType = isEnclosingJp?enclosingStaticTjpType:staticTjpType;
}
ret = new FieldGen(modifiers,jpType,"ajc$tjp_" + tjpFields.size(),getConstantPoolGen()).getField();
addField(ret);
FieldGen fGen = new FieldGen(modifiers,jpType,"ajc$tjp_" + tjpFields.size(),getConstantPool());
addField(fGen);
ret = fGen.getField();
tjpFields.put(shadow, ret);
return ret;
}
@@ -945,11 +955,11 @@ public final class LazyClassGen {
// Modifier.PRIVATE | Modifier.FINAL | Modifier.STATIC,
// classType,
// "aj$class",
// getConstantPoolGen()).getField();
// getConstantPool()).getField();
// addField(ajClassField);
//
// InstructionList il = new InstructionList();
// il.append(new PUSH(getConstantPoolGen(), getClassName()));
// il.append(new PUSH(getConstantPool(), getClassName()));
// il.append(fact.createInvoke("java.lang.Class", "forName", classType,
// new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// il.append(fact.createFieldAccess(getClassName(), ajClassField.getName(),
@@ -970,7 +980,7 @@ public final class LazyClassGen {
if (il==null) {
il= new InstructionList();
}
il.append(new PUSH(getConstantPoolGen(),calculatedSerialVersionUID));
il.append(InstructionFactory.PUSH(getConstantPool(),calculatedSerialVersionUID));
il.append(getFactory().createFieldAccess(getClassName(), "serialVersionUID", BasicType.LONG, Constants.PUTSTATIC));
}
@@ -986,11 +996,11 @@ public final class LazyClassGen {
list.append(fact.createNew(factoryType));
list.append(InstructionFactory.createDup(1));
list.append(new PUSH(getConstantPoolGen(), getFileName()));
list.append(InstructionFactory.PUSH(getConstantPool(), getFileName()));
// load the current Class object
//XXX check that this works correctly for inners/anonymous
list.append(new PUSH(getConstantPoolGen(), getClassName()));
list.append(InstructionFactory.PUSH(getConstantPool(), getClassName()));
//XXX do we need to worry about the fact the theorectically this could throw
//a ClassNotFoundException
list.append(fact.createInvoke("java.lang.Class", "forName", classType,
@@ -1032,13 +1042,13 @@ public final class LazyClassGen {
list.append(InstructionFactory.createLoad(factoryType, 0));
// load the kind
list.append(new PUSH(getConstantPoolGen(), shadow.getKind().getName()));
list.append(InstructionFactory.PUSH(getConstantPool(), shadow.getKind().getName()));
// create the signature
list.append(InstructionFactory.createLoad(factoryType, 0));
if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have optimized factory methods in 1.2
list.append(new PUSH(getConstantPoolGen(), sig.getSignatureString(shadow.getWorld())));
list.append(InstructionFactory.PUSH(getConstantPool(), sig.getSignatureString(shadow.getWorld())));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
@@ -1047,13 +1057,13 @@ public final class LazyClassGen {
} else if (sig.getKind().equals(Member.METHOD)) {
BcelWorld w = shadow.getWorld();
// For methods, push the parts of the signature on.
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w))));
list.append(new PUSH(getConstantPoolGen(),sig.getName()));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterNames(w))));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getExceptions(w))));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getReturnType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName()));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getReturnType())));
// And generate a call to the variant of makeMethodSig() that takes 7 strings
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
@@ -1061,14 +1071,14 @@ public final class LazyClassGen {
new Type[] { Type.STRING,Type.STRING,Type.STRING,Type.STRING,Type.STRING,Type.STRING,Type.STRING },
Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.MONITORENTER)) {
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType())));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
new Type[] { Type.STRING},
Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.MONITOREXIT)) {
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType())));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
@@ -1076,9 +1086,9 @@ public final class LazyClassGen {
Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.HANDLER)) {
BcelWorld w = shadow.getWorld();
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterNames(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w))));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
@@ -1088,22 +1098,22 @@ public final class LazyClassGen {
BcelWorld w = shadow.getWorld();
if (w.isJoinpointArrayConstructionEnabled() && sig.getDeclaringType().isArray()) {
// its the magical new jp
list.append(new PUSH(getConstantPoolGen(),makeString(Modifier.PUBLIC)));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes())));
list.append(new PUSH(getConstantPoolGen(),""));//makeString("")));//sig.getParameterNames(w))));
list.append(new PUSH(getConstantPoolGen(),""));//makeString("")));//sig.getExceptions(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(Modifier.PUBLIC)));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes())));
list.append(InstructionFactory.PUSH(getConstantPool(),""));//makeString("")));//sig.getParameterNames(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),""));//makeString("")));//sig.getExceptions(w))));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING },
Constants.INVOKEVIRTUAL));
} else {
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w))));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterNames(w))));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getExceptions(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w))));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
@@ -1112,16 +1122,16 @@ public final class LazyClassGen {
}
} else if(sig.getKind().equals(Member.FIELD)) {
BcelWorld w = shadow.getWorld();
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w))));
list.append(new PUSH(getConstantPoolGen(),sig.getName()));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName()));
// see pr227401
UnresolvedType dType = sig.getDeclaringType();
if (dType.getTypekind()==TypeKind.PARAMETERIZED ||
dType.getTypekind()==TypeKind.GENERIC) {
dType = sig.getDeclaringType().resolve(world).getGenericType();
}
list.append(new PUSH(getConstantPoolGen(),makeString(dType)));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getReturnType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(dType)));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getReturnType())));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
@@ -1129,13 +1139,13 @@ public final class LazyClassGen {
Constants.INVOKEVIRTUAL));
} else if(sig.getKind().equals(Member.ADVICE)) {
BcelWorld w = shadow.getWorld();
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w))));
list.append(new PUSH(getConstantPoolGen(),sig.getName()));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes())));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterNames(w))));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getExceptions(w))));
list.append(new PUSH(getConstantPoolGen(),makeString((sig.getReturnType()))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName()));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString((sig.getReturnType()))));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
@@ -1143,15 +1153,15 @@ public final class LazyClassGen {
Constants.INVOKEVIRTUAL));
} else if(sig.getKind().equals(Member.STATIC_INITIALIZATION)) {
BcelWorld w = shadow.getWorld();
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w))));
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType())));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w))));
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType())));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
new Type[] { Type.STRING, Type.STRING },
Constants.INVOKEVIRTUAL));
} else {
list.append(new PUSH(getConstantPoolGen(), sig.getSignatureString(shadow.getWorld())));
list.append(InstructionFactory.PUSH(getConstantPool(), sig.getSignatureString(shadow.getWorld())));
list.append(fact.createInvoke(factoryType.getClassName(),
sig.getSignatureMakerName(),
new ObjectType(sig.getSignatureType()),
@@ -1239,12 +1249,20 @@ public final class LazyClassGen {
return myGen.getFileName();
}

private void addField(Field field) {
myGen.addField(field);
// for *new* fields
private void addField(FieldGen field) {
makeSyntheticAndTransientIfNeeded(field);
BcelField bcelField = null;
if (getBcelObjectType() != null) {
bcelField = new BcelField(getBcelObjectType(),field.getField());
} else {
bcelField = new BcelField(getName(),field.getField(),world);
}
fields.add(bcelField);
// myGen.addField(field.getField());
}
private void makeSyntheticAndTransientIfNeeded(Field field) {
private void makeSyntheticAndTransientIfNeeded(FieldGen field) {
if (field.getName().startsWith(NameMangler.PREFIX) &&
!field.getName().startsWith("ajc$interField$") &&
!field.getName().startsWith("ajc$instance$")) {
@@ -1260,33 +1278,29 @@ public final class LazyClassGen {
}
if (!hasSyntheticAttribute(field.getAttributes())) {
// belt and braces, do the attribute even on Java 5 in addition to the modifier flag
Attribute[] oldAttrs = field.getAttributes();
Attribute[] newAttrs = new Attribute[oldAttrs.length + 1];
System.arraycopy(oldAttrs, 0, newAttrs, 0, oldAttrs.length);
ConstantPoolGen cpg = myGen.getConstantPool();
// Attribute[] oldAttrs = field.getAttributes();
// Attribute[] newAttrs = new Attribute[oldAttrs.length + 1];
// System.arraycopy(oldAttrs, 0, newAttrs, 0, oldAttrs.length);
ConstantPool cpg = myGen.getConstantPool();
int index = cpg.addUtf8("Synthetic");
Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg.getConstantPool());
newAttrs[newAttrs.length - 1] = synthetic;
field.setAttributes(newAttrs);
Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg);
field.addAttribute(synthetic);
// newAttrs[newAttrs.length - 1] = synthetic;
// field.setAttributes(newAttrs);
}
}
}
private boolean hasSyntheticAttribute(Attribute[] attributes) {
for (int i = 0; i < attributes.length; i++) {
if (attributes[i].getName().equals("Synthetic")) {
private boolean hasSyntheticAttribute(List attributes) {
for (int i = 0; i < attributes.size(); i++) {
if (((Attribute)attributes.get(i)).getName().equals("Synthetic")) {
return true;
}
}
return false;
}

public void replaceField(Field oldF, Field newF){
myGen.removeField(oldF);
myGen.addField(newF);
}
public void addField(Field field, ISourceLocation sourceLocation) {
public void addField(FieldGen field, ISourceLocation sourceLocation) {
addField(field);
if (!(field.isPrivate()
&& (field.isStatic() || field.isTransient()))) {
@@ -1330,10 +1344,8 @@ public final class LazyClassGen {
}
public boolean forcePublic() {
if (myGen.isPublic()) return false;
myGen.setAccessFlags(Utility.makePublic(myGen.getAccessFlags()));
return true;
public void forcePublic() {
myGen.setModifiers(Utility.makePublic(myGen.getModifiers()));
}

@@ -1352,9 +1364,9 @@ public final class LazyClassGen {
return false;
}
public void addAnnotation(Annotation a) {
public void addAnnotation(AnnotationGen a) {
if (!hasAnnotation(UnresolvedType.forSignature(a.getTypeSignature()))) {
annotations.add(new AnnotationGen(a,getConstantPoolGen(),true));
annotations.add(new AnnotationGen(a,getConstantPool(),true));
}
}
@@ -1388,9 +1400,9 @@ public final class LazyClassGen {
*/
public String allocateField(String prefix) {
int highestAllocated = -1;
Field[] fs = getFieldGens();
for (int i = 0; i < fs.length; i++) {
Field field = fs[i];
List/*BcelField*/ fs = getFieldGens();
for (int i = 0; i < fs.size(); i++) {
BcelField field = (BcelField)fs.get(i);
if (field.getName().startsWith(prefix)) {
try {
int num = Integer.parseInt(field.getName().substring(prefix.length()));

+ 131
- 193
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java View File

@@ -33,28 +33,26 @@ import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Synthetic;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.generic.BranchHandle;
import org.aspectj.apache.bcel.generic.BranchInstruction;
import org.aspectj.apache.bcel.generic.CPInstruction;
import org.aspectj.apache.bcel.generic.ClassGenException;
import org.aspectj.apache.bcel.generic.CodeExceptionGen;
import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionBranch;
import org.aspectj.apache.bcel.generic.InstructionComparator;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionSelect;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.LineNumberGen;
import org.aspectj.apache.bcel.generic.LineNumberTag;
import org.aspectj.apache.bcel.generic.LocalVariableGen;
import org.aspectj.apache.bcel.generic.LocalVariableInstruction;
import org.aspectj.apache.bcel.generic.LocalVariableTag;
import org.aspectj.apache.bcel.generic.MethodGen;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.Select;
import org.aspectj.apache.bcel.generic.Tag;
import org.aspectj.apache.bcel.generic.TargetLostException;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.MessageUtil;
@@ -73,6 +71,7 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.tools.Traceable;



/**
* A LazyMethodGen should be treated as a MethodGen. It's our way of abstracting over the
* low-level Method objects. It converts through {@link MethodGen} to create
@@ -90,14 +89,14 @@ import org.aspectj.weaver.tools.Traceable;
public final class LazyMethodGen implements Traceable {
private static final int ACC_SYNTHETIC = 0x1000;
private int accessFlags;
private Type returnType;
private final String name;
private int accessFlags;
private Type returnType;
private final String name;
private Type[] argumentTypes;
//private final String[] argumentNames;
private String[] declaredExceptions;
private InstructionList body; // leaving null for abstracts
private Attribute[] attributes;
private List attributes;
private List newAnnotations;
private final LazyClassGen enclosingClass;
private BcelMethod memberView;
@@ -106,6 +105,8 @@ public final class LazyMethodGen implements Traceable {

/*
* We use LineNumberTags and not Gens.
*
* This option specifies whether we let the BCEL classes create LineNumberGens and LocalVariableGens
* or if we make it create LineNumberTags and LocalVariableTags. Up until 1.5.1 we always created
* Gens - then on return from the MethodGen ctor we took them apart, reprocessed them all and
@@ -118,12 +119,7 @@ public final class LazyMethodGen implements Traceable {
* instructions it targets, it relies on the instructions targetting *it* - this reduces the amount
* of targeter manipulation we have to do.
*
* Because this *could* go wrong - it passes all our tests, but you never know, the option:
* -Xset:optimizeWithTags=false
* will turn it *OFF*
*/
public static boolean avoidUseOfBcelGenObjects = true;
public static boolean checkedXsetOption = false;

/** This is nonnull if this method is the result of an "inlining". We currently
* copy methods into other classes for around advice. We add this field so
@@ -171,7 +167,7 @@ public final class LazyMethodGen implements Traceable {
} else {
body = null;
}
this.attributes = new Attribute[0];
this.attributes = new ArrayList();
this.enclosingClass = enclosingClass;
assertGoodBody();

@@ -211,7 +207,33 @@ public final class LazyMethodGen implements Traceable {
}
this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
this.accessFlags = m.getAccessFlags();
this.accessFlags = m.getModifiers();
this.name = m.getName();

// @AJ advice are not inlined by default since requires further analysis
// and weaving ordering control
// TODO AV - improve - note: no room for improvement as long as aspects are reweavable
// since the inlined version with wrappers and an to be done annotation to keep
// inline state will be garbaged due to reweavable impl
if (memberView != null && isAdviceMethod()) {
if (enclosingClass.getType().isAnnotationStyleAspect()) {
//TODO we could check for @Around advice as well
this.canInline = false;
}
}
}
public LazyMethodGen(BcelMethod m,LazyClassGen enclosingClass) {
savedMethod = m.getMethod();
this.enclosingClass = enclosingClass;
if (!(m.isAbstract() || m.isNative()) && savedMethod.getCode() == null) {
throw new RuntimeException("bad non-abstract method with no code: " + m + " on " + enclosingClass);
}
if ((m.isAbstract() || m.isNative()) && savedMethod.getCode() != null) {
throw new RuntimeException("bad abstract method with code: " + m + " on " + enclosingClass);
}
//this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
this.memberView = m;
this.accessFlags = savedMethod.getModifiers();
this.name = m.getName();

// @AJ advice are not inlined by default since requires further analysis
@@ -225,6 +247,7 @@ public final class LazyMethodGen implements Traceable {
this.canInline = false;
}
}
}
public boolean hasDeclaredLineNumberInfo() {
@@ -278,21 +301,9 @@ public final class LazyMethodGen implements Traceable {
private void initialize() {
if (returnType != null) return;
// Check whether we need to configure the optimization
if (!checkedXsetOption) {
Properties p = enclosingClass.getWorld().getExtraConfiguration();
if (p!=null) {
String s = p.getProperty("optimizeWithTags","true");
avoidUseOfBcelGenObjects = s.equalsIgnoreCase("true");
if (!avoidUseOfBcelGenObjects)
enclosingClass.getWorld().getMessageHandler().handleMessage(MessageUtil.info("[optimizeWithTags=false] Disabling optimization to use Tags rather than Gens"));
}
checkedXsetOption=true;
}
//System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " + savedMethod);
MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPoolGen(),avoidUseOfBcelGenObjects);
MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(),true);
this.returnType = gen.getReturnType();
this.argumentTypes = gen.getArgumentTypes();
@@ -318,13 +329,9 @@ public final class LazyMethodGen implements Traceable {

unpackHandlers(gen);
if (avoidUseOfBcelGenObjects) {
ensureAllLineNumberSetup(gen);
highestLineNumber = gen.getHighestlinenumber();
} else {
unpackLineNumbers(gen);
unpackLocals(gen);
}
ensureAllLineNumberSetup(gen);
highestLineNumber = gen.getHighestlinenumber();
}
assertGoodBody();
@@ -388,29 +395,6 @@ public final class LazyMethodGen implements Traceable {
}
}

private void unpackLineNumbers(MethodGen gen) {
LineNumberTag lr = null;
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
InstructionTargeter[] targeters = ih.getTargeters();
if (targeters != null) {
for (int i = targeters.length - 1; i >= 0; i--) {
InstructionTargeter targeter = targeters[i];
if (targeter instanceof LineNumberGen) {
LineNumberGen lng = (LineNumberGen) targeter;
lng.updateTarget(ih, null);
int lineNumber = lng.getSourceLine();
if (highestLineNumber < lineNumber) highestLineNumber = lineNumber;
lr = new LineNumberTag(lineNumber);
}
}
}
if (lr != null) {
ih.addTargeter(lr);
}
}
gen.removeLineNumbers();
}

/**
* On entry to this method we have a method whose instruction stream contains a few instructions
* that have line numbers assigned to them (LineNumberTags). The aim is to ensure every instruction
@@ -437,33 +421,6 @@ public final class LazyMethodGen implements Traceable {
}
}
}

private void unpackLocals(MethodGen gen) {
Set locals = new HashSet();
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
InstructionTargeter[] targeters = ih.getTargeters();
List ends = new ArrayList(0);
if (targeters != null) {
for (int i = targeters.length - 1; i >= 0; i--) {
InstructionTargeter targeter = targeters[i];
if (targeter instanceof LocalVariableGen) {
LocalVariableGen lng = (LocalVariableGen) targeter;
LocalVariableTag lr = new LocalVariableTag(lng.getType().getSignature()/*BcelWorld.fromBcel(lng.getType())*/, lng.getName(), lng.getIndex(), lng.getStart().getPosition());
if (lng.getStart() == ih) {
locals.add(lr);
} else {
ends.add(lr);
}
}
}
}
for (Iterator i = locals.iterator(); i.hasNext(); ) {
ih.addTargeter((LocalVariableTag) i.next());
}
locals.removeAll(ends);
}
gen.removeLocalVariables();
}
// ===============
@@ -506,7 +463,8 @@ public final class LazyMethodGen implements Traceable {
// =============================

public String toString() {
WeaverVersionInfo weaverVersion = enclosingClass.getBcelObjectType().getWeaverVersionAttribute();
BcelObjectType bot = enclosingClass.getBcelObjectType();
WeaverVersionInfo weaverVersion = (bot==null?WeaverVersionInfo.CURRENT:bot.getWeaverVersionAttribute());
return toLongString(weaverVersion);
}

@@ -588,7 +546,7 @@ public final class LazyMethodGen implements Traceable {
if (enclosingClass != null && enclosingClass.getType() != null) {
context = enclosingClass.getType().getSourceContext();
}
List as = BcelAttributes.readAjAttributes(getClassName(),attributes, context,null,weaverVersion);
List as = BcelAttributes.readAjAttributes(getClassName(), (Attribute[])attributes.toArray(new Attribute[]{}), context,null,weaverVersion);
if (! as.isEmpty()) {
out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger...
}
@@ -606,7 +564,7 @@ public final class LazyMethodGen implements Traceable {
List ranges;

BodyPrinter(PrintStream out) {
this.pool = enclosingClass.getConstantPoolGen().getConstantPool();
this.pool = enclosingClass.getConstantPool();
this.body = getBody();
this.out = out;
}
@@ -634,7 +592,7 @@ public final class LazyMethodGen implements Traceable {
if (r.getStart() == ih) {
insertHandler(r, exnTable);
}
} else if (t instanceof BranchInstruction) {
} else if (t instanceof InstructionBranch) {
if (pendingLabel == null) {
pendingLabel = "L" + lcounter++;
}
@@ -736,14 +694,13 @@ public final class LazyMethodGen implements Traceable {
printLabel((String) labelMap.get(h), depth);
Instruction inst = h.getInstruction();
if (inst instanceof CPInstruction) {
CPInstruction cpinst = (CPInstruction) inst;
out.print(Constants.OPCODE_NAMES[cpinst.getOpcode()].toUpperCase());
if (inst.isConstantPoolInstruction()) {
out.print(Constants.OPCODE_NAMES[inst.opcode].toUpperCase());
out.print(" ");
out.print(pool.constantToString(pool.getConstant(cpinst.getIndex())));
} else if (inst instanceof Select) {
Select sinst = (Select) inst;
out.println(Constants.OPCODE_NAMES[sinst.getOpcode()].toUpperCase());
out.print(pool.constantToString(pool.getConstant(inst.getIndex())));
} else if (inst instanceof InstructionSelect) {
InstructionSelect sinst = (InstructionSelect) inst;
out.println(Constants.OPCODE_NAMES[sinst.opcode].toUpperCase());
int[] matches = sinst.getMatchs();
InstructionHandle[] targets = sinst.getTargets();
InstructionHandle defaultTarget = sinst.getTarget();
@@ -760,15 +717,15 @@ public final class LazyMethodGen implements Traceable {
out.print(" ");
out.print("default: \t");
out.print(labelMap.get(defaultTarget));
} else if (inst instanceof BranchInstruction) {
BranchInstruction brinst = (BranchInstruction) inst;
} else if (inst instanceof InstructionBranch) {
InstructionBranch brinst = (InstructionBranch) inst;
out.print(Constants.OPCODE_NAMES[brinst.getOpcode()].toUpperCase());
out.print(" ");
out.print(labelMap.get(brinst.getTarget()));
} else if (inst instanceof LocalVariableInstruction) {
LocalVariableInstruction lvinst = (LocalVariableInstruction) inst;
} else if (inst.isLocalVariableInstruction()) {
//LocalVariableInstruction lvinst = (LocalVariableInstruction) inst;
out.print(inst.toString(false).toUpperCase());
int index = lvinst.getIndex();
int index = inst.getIndex();
LocalVariableTag tag = getLocalVariableTag(h, index);
if (tag != null) {
out.print(" // ");
@@ -914,7 +871,7 @@ public final class LazyMethodGen implements Traceable {
return body != null;
}

public Attribute[] getAttributes() {
public List/*Attribute*/ getAttributes() {
return attributes;
}

@@ -947,13 +904,13 @@ public final class LazyMethodGen implements Traceable {
getName(),
getEnclosingClass().getName(),
new InstructionList(),
getEnclosingClass().getConstantPoolGen());
getEnclosingClass().getConstantPool());
for (int i = 0, len = declaredExceptions.length; i < len; i++) {
gen.addException(declaredExceptions[i]);
}
for (int i = 0, len = attributes.length; i < len; i++) {
gen.addAttribute(attributes[i]);
for (int i = 0, len = attributes.size(); i < len; i++) {
gen.addAttribute((Attribute)attributes.get(i));
}
if (newAnnotations!=null) {
@@ -966,7 +923,7 @@ public final class LazyMethodGen implements Traceable {
if (memberView!=null && memberView.getAnnotations()!=null && memberView.getAnnotations().length!=0) {
AnnotationX[] ans = memberView.getAnnotations();
for (int i = 0, len = ans.length; i < len; i++) {
Annotation a= ans[i].getBcelAnnotation();
AnnotationGen a= ans[i].getBcelAnnotation();
gen.addAnnotation(new AnnotationGen(a,gen.getConstantPool(),true));
}
}
@@ -976,9 +933,9 @@ public final class LazyMethodGen implements Traceable {
gen.setModifiers(gen.getModifiers() | ACC_SYNTHETIC);
}
// belt and braces, do the attribute even on Java 5 in addition to the modifier flag
ConstantPoolGen cpg = gen.getConstantPool();
ConstantPool cpg = gen.getConstantPool();
int index = cpg.addUtf8("Synthetic");
gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg.getConstantPool()));
gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg));
}
if (hasBody()) {
@@ -1045,7 +1002,7 @@ public final class LazyMethodGen implements Traceable {
Instruction oldInstruction = oldInstructionHandle.getInstruction();
Instruction newInstruction = newInstructionHandle.getInstruction();
if (oldInstruction instanceof BranchInstruction) {
if (oldInstruction instanceof InstructionBranch) {
handleBranchInstruction(map, oldInstruction, newInstruction);
}
@@ -1148,27 +1105,20 @@ public final class LazyMethodGen implements Traceable {
}

private void handleBranchInstruction(Map map, Instruction oldInstruction, Instruction newInstruction) {
BranchInstruction oldBranchInstruction = (BranchInstruction) oldInstruction;
BranchInstruction newBranchInstruction = (BranchInstruction) newInstruction;
InstructionBranch oldBranchInstruction = (InstructionBranch) oldInstruction;
InstructionBranch newBranchInstruction = (InstructionBranch) newInstruction;
InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old target
// try {
// New target is in hash map
newBranchInstruction.setTarget(remap(oldTarget, map));
// } catch (NullPointerException e) {
// print();
// System.out.println("Was trying to remap " + bi);
// System.out.println("who's target was supposedly " + itarget);
// throw e;
// }
if (oldBranchInstruction instanceof Select) {
// Either LOOKUPSWITCH or TABLESWITCH
InstructionHandle[] oldTargets = ((Select) oldBranchInstruction).getTargets();
InstructionHandle[] newTargets = ((Select) newBranchInstruction).getTargets();
if (oldBranchInstruction instanceof InstructionSelect) {
// Either LOOKUPSWITCH or TABLESWITCH
InstructionHandle[] oldTargets = ((InstructionSelect) oldBranchInstruction).getTargets();
InstructionHandle[] newTargets = ((InstructionSelect) newBranchInstruction).getTargets();
for (int k = oldTargets.length - 1; k >= 0; k--) {
// Update all targets
for (int k = oldTargets.length - 1; k >= 0; k--) {
// Update all targets
newTargets[k] = remap(oldTargets[k], map);
newTargets[k].addTargeter(newBranchInstruction);
}
@@ -1206,8 +1156,8 @@ public final class LazyMethodGen implements Traceable {
Instruction i = ih.getInstruction();
Instruction c = Utility.copyInstruction(i);

if (c instanceof BranchInstruction)
map.put(ih, intoList.append((BranchInstruction) c));
if (c instanceof InstructionBranch)
map.put(ih, intoList.append((InstructionBranch) c));
else
map.put(ih, intoList.append(c));
}
@@ -1337,80 +1287,71 @@ public final class LazyMethodGen implements Traceable {
}
public static void assertGoodBody(InstructionList il, String from) {
if (true) return; // only to be enabled for debugging // should be switchonable via an option
StringBuffer assertionLog = new StringBuffer();
assertionLog.append("Checking state of an instruction body, from="+from+"\n");
try {
if (il == null) return;
Set body = new HashSet();
Stack ranges = new Stack();
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
body.add(ih);
if (ih.getInstruction() instanceof BranchInstruction) {
body.add(ih.getInstruction());
}
}
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
assertGoodHandle(ih, body, ranges, from, assertionLog);
InstructionTargeter[] ts = ih.getTargeters();
if (ts != null) {
for (int i = ts.length - 1; i >= 0; i--) {
assertGoodTargeter(ts[i], ih, body, from, assertionLog);
}
}
}
} catch (RuntimeException re) {
System.err.println(assertionLog.toString());
throw re;
}
if (true) return; // only to be enabled for debugging
if (il == null) return;
Set body = new HashSet();
Stack ranges = new Stack();
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
body.add(ih);
if (ih.getInstruction() instanceof InstructionBranch) {
body.add(ih.getInstruction());
}
}
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
assertGoodHandle(ih, body, ranges, from);
InstructionTargeter[] ts = ih.getTargeters();
if (ts != null) {
for (int i = ts.length - 1; i >= 0; i--) {
assertGoodTargeter(ts[i], ih, body, from);
}
}
}
}

private static void assertGoodHandle(InstructionHandle ih, Set body, Stack ranges, String from, StringBuffer log) {
private static void assertGoodHandle(InstructionHandle ih, Set body, Stack ranges, String from) {
Instruction inst = ih.getInstruction();
if ((inst instanceof BranchInstruction) ^ (ih instanceof BranchHandle)) {
if ((inst instanceof InstructionBranch) ^ (ih instanceof BranchHandle)) {
throw new BCException("bad instruction/handle pair in " + from);
}
if (Range.isRangeHandle(ih)) {
log.append("Checking range handle '"+ih+"'\n");
assertGoodRangeHandle(ih, body, ranges, from,log);
} else if (inst instanceof BranchInstruction) {
assertGoodBranchInstruction((BranchHandle) ih, (BranchInstruction) inst, body, ranges, from, log);
assertGoodRangeHandle(ih, body, ranges, from);
} else if (inst instanceof InstructionBranch) {
assertGoodBranchInstruction((BranchHandle) ih, (InstructionBranch) inst, body, ranges, from);
}
}

private static void assertGoodBranchInstruction(
BranchHandle ih,
BranchInstruction inst,
InstructionBranch inst,
Set body,
Stack ranges,
String from, StringBuffer log)
String from)
{
if (ih.getTarget() != inst.getTarget()) {
throw new BCException("bad branch instruction/handle pair in " + from);
}
InstructionHandle target = ih.getTarget();
assertInBody(target, body, from, log);
assertInBody(target, body, from);
assertTargetedBy(target, inst, from);
if (inst instanceof Select) {
Select sel = (Select) inst;
if (inst instanceof InstructionSelect) {
InstructionSelect sel = (InstructionSelect) inst;
InstructionHandle[] itargets = sel.getTargets();
for (int k = itargets.length - 1; k >= 0; k--) {
assertInBody(itargets[k], body, from, log);
assertInBody(itargets[k], body, from);
assertTargetedBy(itargets[k], inst, from);
}
}
}

/** ih is an InstructionHandle or a BranchInstruction */
private static void assertInBody(Object ih, Set body, String from,StringBuffer log) {
private static void assertInBody(Object ih, Set body, String from) {
if (! body.contains(ih)) throw new BCException("thing not in body in " + from);
}

private static void assertGoodRangeHandle(InstructionHandle ih, Set body, Stack ranges, String from, StringBuffer log) {
private static void assertGoodRangeHandle(InstructionHandle ih, Set body, Stack ranges, String from) {
Range r = getRangeAndAssertExactlyOne(ih, from);
assertGoodRange(r, body, from, log);
assertGoodRange(r, body, from);
if (r.getStart() == ih) {
ranges.push(r);
} else if (r.getEnd() == ih) {
@@ -1419,23 +1360,18 @@ public final class LazyMethodGen implements Traceable {
}
}
private static void assertGoodRange(Range r, Set body, String from, StringBuffer log) {
assertInBody(r.getStart(), body, from, log);
private static void assertGoodRange(Range r, Set body, String from) {
assertInBody(r.getStart(), body, from);
assertRangeHandle(r.getStart(), from);
assertTargetedBy(r.getStart(), r, from);

assertInBody(r.getEnd(), body, from, log);
assertInBody(r.getEnd(), body, from);
assertRangeHandle(r.getEnd(), from);
assertTargetedBy(r.getEnd(), r, from);
if (r instanceof ExceptionRange) {
ExceptionRange er = (ExceptionRange) r;
log.append("Checking exception range \n");
if (!body.contains(er.getHandler())) {
log.append("Exception handler not within body\n");
throw new BCException("exception handler not in body");
}
// assertInBody(er.getHandler(), body, from, log);
assertInBody(er.getHandler(), body, from);
assertTargetedBy(er.getHandler(), r, from);
}
}
@@ -1465,11 +1401,11 @@ public final class LazyMethodGen implements Traceable {
if (r instanceof ExceptionRange) {
if (((ExceptionRange)r).getHandler() == target) return;
}
} else if (targeter instanceof BranchInstruction) {
BranchInstruction bi = (BranchInstruction) targeter;
} else if (targeter instanceof InstructionBranch) {
InstructionBranch bi = (InstructionBranch) targeter;
if (bi.getTarget() == target) return;
if (targeter instanceof Select) {
Select sel = (Select) targeter;
if (targeter instanceof InstructionSelect) {
InstructionSelect sel = (InstructionSelect) targeter;
InstructionHandle[] itargets = sel.getTargets();
for (int k = itargets.length - 1; k >= 0; k--) {
if (itargets[k] == target) return;
@@ -1499,13 +1435,13 @@ public final class LazyMethodGen implements Traceable {
InstructionTargeter t,
InstructionHandle ih,
Set body,
String from, StringBuffer log)
String from)
{
assertTargets(t, ih, from);
if (t instanceof Range) {
assertGoodRange((Range) t, body, from, log);
} else if (t instanceof BranchInstruction) {
assertInBody(t, body, from, log);
assertGoodRange((Range) t, body, from);
} else if (t instanceof InstructionBranch) {
assertInBody(t, body, from);
}
}
@@ -1513,6 +1449,7 @@ public final class LazyMethodGen implements Traceable {
// ----
boolean isAdviceMethod() {
if (memberView==null) return false;
return memberView.getAssociatedShadowMunger() != null;
}
@@ -1576,10 +1513,11 @@ public final class LazyMethodGen implements Traceable {
* @param attr
*/
public void addAttribute(Attribute attr) {
Attribute[] newAttributes = new Attribute[attributes.length + 1];
System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
newAttributes[attributes.length] = attr;
attributes = newAttributes;
attributes.add(attr);
// Attribute[] newAttributes = new Attribute[attributes.length + 1];
// System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
// newAttributes[attributes.length] = attr;
// attributes = newAttributes;
}

public String toTraceString() {

+ 2
- 2
weaver/src/org/aspectj/weaver/bcel/Range.java View File

@@ -15,8 +15,8 @@ package org.aspectj.weaver.bcel;

import java.util.Map;

import org.aspectj.apache.bcel.generic.IMPDEP1;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
@@ -224,7 +224,7 @@ abstract class Range implements InstructionTargeter {

// note that this is STUPIDLY copied by Instruction.copy(), so don't do that.

public static final Instruction RANGEINSTRUCTION = new IMPDEP1();
public static final Instruction RANGEINSTRUCTION = InstructionConstants.IMPDEP1;
// ----


+ 12
- 14
weaver/src/org/aspectj/weaver/bcel/ShadowRange.java View File

@@ -13,17 +13,15 @@

package org.aspectj.weaver.bcel;

import org.aspectj.apache.bcel.generic.BranchInstruction;
import org.aspectj.apache.bcel.generic.IndexedInstruction;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionBranch;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionSelect;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.LocalVariableInstruction;
import org.aspectj.apache.bcel.generic.LocalVariableTag;
import org.aspectj.apache.bcel.generic.RET;
import org.aspectj.apache.bcel.generic.Select;
import org.aspectj.apache.bcel.generic.TargetLostException;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.IntMap;
@@ -76,17 +74,17 @@ final class ShadowRange extends Range {

// Now we add it to the new instruction list.
InstructionHandle freshIh;
if (freshI instanceof BranchInstruction) {
if (freshI instanceof InstructionBranch) {
//If it's a targeting instruction,
// update the target(s) to point to the new copy instead of the old copy.
BranchInstruction oldBranch = (BranchInstruction) oldI;
BranchInstruction freshBranch = (BranchInstruction) freshI;
InstructionBranch oldBranch = (InstructionBranch) oldI;
InstructionBranch freshBranch = (InstructionBranch) freshI;
InstructionHandle oldTarget = oldBranch.getTarget();
oldTarget.removeTargeter(oldBranch);
oldTarget.addTargeter(freshBranch);
if (freshBranch instanceof Select) {
Select oldSelect = (Select) oldI;
Select freshSelect = (Select) freshI;
if (freshBranch instanceof InstructionSelect) {
InstructionSelect oldSelect = (InstructionSelect) oldI;
InstructionSelect freshSelect = (InstructionSelect) freshI;
InstructionHandle[] oldTargets = freshSelect.getTargets();
for (int k = oldTargets.length - 1; k >= 0; k--) {
oldTargets[k].removeTargeter(oldSelect);
@@ -161,9 +159,9 @@ final class ShadowRange extends Range {
// do compaction/expansion: allocate a new local variable, and modify the remap
// to handle it. XXX We're doing the safe thing and allocating ALL these local variables
// as double-wides, in case the location is found to hold a double-wide later.
if (freshI instanceof LocalVariableInstruction || freshI instanceof RET) {
IndexedInstruction indexedI = (IndexedInstruction) freshI;
int oldIndex = indexedI.getIndex();
if (freshI.isLocalVariableInstruction() || freshI instanceof RET) {
// IndexedInstruction indexedI = (IndexedInstruction) freshI;
int oldIndex = freshI.getIndex();
int freshIndex;
if (! remap.hasKey(oldIndex)) {
freshIndex = freshMethod.allocateLocal(2);
@@ -171,7 +169,7 @@ final class ShadowRange extends Range {
} else {
freshIndex = remap.get(oldIndex);
}
indexedI.setIndex(freshIndex);
freshI.setIndex(freshIndex);
}
// System.err.println("JUST COPIED: " + oldIh.getInstruction().toString(freshMethod.getEnclosingClass().getConstantPoolGen().getConstantPool())
// + " INTO " + freshIh.getInstruction().toString(freshMethod.getEnclosingClass().getConstantPoolGen().getConstantPool()));

+ 76
- 69
weaver/src/org/aspectj/weaver/bcel/Utility.java View File

@@ -24,36 +24,36 @@ import java.util.Hashtable;
import java.util.List;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.ClassParser;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue;
import org.aspectj.apache.bcel.classfile.Unknown;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValueGen;
import org.aspectj.apache.bcel.generic.ArrayType;
import org.aspectj.apache.bcel.generic.BIPUSH;
import org.aspectj.apache.bcel.generic.BasicType;
import org.aspectj.apache.bcel.generic.BranchInstruction;
import org.aspectj.apache.bcel.generic.ConstantPushInstruction;
import org.aspectj.apache.bcel.generic.INSTANCEOF;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionByte;
import org.aspectj.apache.bcel.generic.InstructionCP;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionSelect;
import org.aspectj.apache.bcel.generic.InstructionShort;
import org.aspectj.apache.bcel.generic.InstructionTargeter;
import org.aspectj.apache.bcel.generic.InvokeInstruction;
import org.aspectj.apache.bcel.generic.LDC;
import org.aspectj.apache.bcel.generic.LineNumberTag;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.ReferenceType;
import org.aspectj.apache.bcel.generic.SIPUSH;
import org.aspectj.apache.bcel.generic.SWITCH;
import org.aspectj.apache.bcel.generic.Select;
import org.aspectj.apache.bcel.generic.SwitchBuilder;
import org.aspectj.apache.bcel.generic.TargetLostException;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.Lint;
@@ -207,12 +207,8 @@ public class Utility {
kind = Constants.INVOKEVIRTUAL;
}

return fact.createInvoke(
declaringClass.getClassName(),
newMethod.getName(),
Type.getReturnType(newMethod.getSignature()),
Type.getArgumentTypes(newMethod.getSignature()),
kind);
String sig = newMethod.getSignature();
return fact.createInvoke(declaringClass.getClassName(),newMethod.getName(),sig,kind);
}
public static byte[] stringToUTF(String s) {
@@ -231,7 +227,7 @@ public class Utility {
(t instanceof ArrayType)
? fact.getConstantPool().addArrayClass((ArrayType)t)
: fact.getConstantPool().addClass((ObjectType)t);
return new INSTANCEOF(cpoolEntry);
return new InstructionCP(Constants.INSTANCEOF,cpoolEntry);
}

public static Instruction createInvoke(
@@ -276,11 +272,17 @@ public class Utility {
kind);
}

private static String[] argNames = new String[] { "arg0", "arg1", "arg2", "arg3", "arg4" };
// ??? these should perhaps be cached. Remember to profile this to see if it's a problem.
public static String[] makeArgNames(int n) {
String[] ret = new String[n];
for (int i=0; i<n; i++) {
ret[i] = "arg" + i;
if (i < 5) {
ret[i] = argNames[i];
} else {
ret[i] = "arg" + i;
}
}
return ret;
}
@@ -384,7 +386,13 @@ public class Utility {
Type from = BcelWorld.makeBcelType(fromType);
Type to = BcelWorld.makeBcelType(toType);
try {
il.append(fact.createCast(from, to));
Instruction i = fact.createCast(from, to);
if (i!=null) {
il.append(i);
} else {
il.append(fact.createCast(from, Type.INT));
il.append(fact.createCast(Type.INT, to));
}
} catch (RuntimeException e) {
il.append(fact.createCast(from, Type.INT));
il.append(fact.createCast(Type.INT, to));
@@ -513,11 +521,12 @@ public class Utility {
case 5: inst = InstructionConstants.ICONST_5; break;
}
if (i <= Byte.MAX_VALUE && i >= Byte.MIN_VALUE) {
inst = new BIPUSH((byte)i);
inst = new InstructionByte(Constants.BIPUSH,(byte)i);
} else if (i <= Short.MAX_VALUE && i >= Short.MIN_VALUE) {
inst = new SIPUSH((short)i);
inst = new InstructionShort(Constants.SIPUSH,(short)i);
} else {
inst = new LDC(fact.getClassGen().getConstantPool().addInteger(i));
int ii = fact.getClassGen().getConstantPool().addInteger(i);
inst = new InstructionCP(i<=Constants.MAX_BYTE?Constants.LDC:Constants.LDC_W,ii);
}
return inst;
}
@@ -555,17 +564,6 @@ public class Utility {
* @param branchInstruction the branch instruction to replace ih with
* @param enclosingMethod where to find ih's instruction list.
*/
public static void replaceInstruction(
InstructionHandle ih,
BranchInstruction branchInstruction,
LazyMethodGen enclosingMethod)
{
InstructionList il = enclosingMethod.getBody();
InstructionHandle fresh = il.append(ih, branchInstruction);
deleteInstruction(ih, fresh, enclosingMethod);
}
public static void replaceInstruction(
InstructionHandle ih,
InstructionList replacementInstructions,
@@ -635,8 +633,8 @@ public class Utility {
* </pre>
*/
public static Instruction copyInstruction(Instruction i) {
if (i instanceof Select) {
Select freshSelect = (Select)i;
if (i instanceof InstructionSelect) {
InstructionSelect freshSelect = (InstructionSelect)i;
// Create a new targets array that looks just like the existing one
InstructionHandle[] targets = new InstructionHandle[freshSelect.getTargets().length];
@@ -645,9 +643,8 @@ public class Utility {
}
// Create a new select statement with the new targets array
SWITCH switchStatement =
new SWITCH(freshSelect.getMatchs(), targets, freshSelect.getTarget());
return (Select)switchStatement.getInstruction();
return new SwitchBuilder(freshSelect.getMatchs(), targets, freshSelect.getTarget()).getInstruction();
} else {
return i.copy(); // Use clone for shallow copy...
}
@@ -699,6 +696,7 @@ public class Utility {
// assumes that there is no already extant source line tag. Otherwise we'll have to be better.
public static void setSourceLine(InstructionHandle ih, int lineNumber) {
// OPTIMIZE LineNumberTag instances for the same line could be shared throughout a method...
ih.addTargeter(new LineNumberTag(lineNumber));
}

@@ -729,7 +727,8 @@ public class Utility {
}

public static boolean isConstantPushInstruction(Instruction i) {
return (i instanceof ConstantPushInstruction) || (i instanceof LDC);
long ii= Constants.instFlags[i.opcode];
return ((ii&Constants.PUSH_INST)!=0 && (ii&Constants.CONSTANT_INST)!=0);
}
/**
@@ -753,11 +752,11 @@ public class Utility {
suppressed = true;
} else { // (2)
// We know the value is an array value
ArrayElementValue array = (ArrayElementValue)((ElementNameValuePair)vals.get(0)).getValue();
ElementValue[] values = array.getElementValuesArray();
ArrayElementValueGen array = (ArrayElementValueGen)((ElementNameValuePairGen)vals.get(0)).getValue();
ElementValueGen[] values = array.getElementValuesArray();
for (int j = 0; j < values.length; j++) {
// We know values in the array are strings
SimpleElementValue value = (SimpleElementValue)values[j];
SimpleElementValueGen value = (SimpleElementValueGen)values[j];
if (value.getValueString().equals(lintkey)) {
suppressed = true;
}
@@ -785,11 +784,11 @@ public class Utility {
suppressedWarnings.addAll(lint.allKinds());
} else { // (2)
// We know the value is an array value
ArrayElementValue array = (ArrayElementValue)((ElementNameValuePair)vals.get(0)).getValue();
ElementValue[] values = array.getElementValuesArray();
ArrayElementValueGen array = (ArrayElementValueGen)((ElementNameValuePairGen)vals.get(0)).getValue();
ElementValueGen[] values = array.getElementValuesArray();
for (int j = 0; j < values.length; j++) {
// We know values in the array are strings
SimpleElementValue value = (SimpleElementValue)values[j];
SimpleElementValueGen value = (SimpleElementValueGen)values[j];
Lint.Kind lintKind = lint.getLintKind(value.getValueString());
if (lintKind != null) suppressedWarnings.add(lintKind);
}
@@ -800,25 +799,33 @@ public class Utility {
}
// not yet used...
public static boolean isSimple(Method method) {
if (method.getCode()==null) return true;
if (method.getCode().getCode().length>10) return false;
InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive!
InstructionHandle InstrHandle = instrucs.getStart();
while (InstrHandle != null) {
Instruction Instr = InstrHandle.getInstruction();
int opCode = Instr.getOpcode();
// if current instruction is a branch instruction, see if it's a backward branch.
// if it is return immediately (can't be trivial)
if (Instr instanceof BranchInstruction) {
BranchInstruction BI = (BranchInstruction) Instr;
if (BI.getIndex() < 0) return false;
} else if (Instr instanceof InvokeInstruction) {
// if current instruction is an invocation, indicate that it can't be trivial
return false;
}
InstrHandle = InstrHandle.getNext();
}
return true;
}
// public static boolean isSimple(Method method) {
// if (method.getCode()==null) return true;
// if (method.getCode().getCode().length>10) return false;
// InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive!
// InstructionHandle InstrHandle = instrucs.getStart();
// while (InstrHandle != null) {
// Instruction Instr = InstrHandle.getInstruction();
// int opCode = Instr.opcode;
// // if current instruction is a branch instruction, see if it's a backward branch.
// // if it is return immediately (can't be trivial)
// if (Instr instanceof InstructionBranch) {
// // InstructionBranch BI = (InstructionBranch) Instr;
// if (Instr.getIndex() < 0) return false;
// } else if (Instr instanceof InvokeInstruction) {
// // if current instruction is an invocation, indicate that it can't be trivial
// return false;
// }
// InstrHandle = InstrHandle.getNext();
// }
// return true;
// }

public static Attribute bcelAttribute(AjAttribute a, ConstantPool pool) {
int nameIndex = pool.addUtf8(a.getNameString());
byte[] bytes = a.getBytes();
int length = bytes.length;
return new Unknown(nameIndex, length, bytes, pool);
}
}

+ 2
- 1
weaver/src/org/aspectj/weaver/patterns/PatternParser.java View File

@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Set;

import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
@@ -1268,7 +1269,7 @@ public class PatternParser {
TypePattern declaringType;
NamePattern name = null;
Member.Kind kind;
MemberKind kind;
// here we can check for 'new'
if (maybeEatNew(returnType)) {
kind = Member.CONSTRUCTOR;

+ 5
- 4
weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java View File

@@ -36,6 +36,7 @@ import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.Constants;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.JoinPointSignature;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.NewFieldTypeMunger;
@@ -47,7 +48,7 @@ import org.aspectj.weaver.World;


public class SignaturePattern extends PatternNode {
private Member.Kind kind;
private MemberKind kind;
private ModifiersPattern modifiers;
private TypePattern returnType;
private TypePattern declaringType;
@@ -57,7 +58,7 @@ public class SignaturePattern extends PatternNode {
private AnnotationTypePattern annotationPattern;
private transient int hashcode = -1;
public SignaturePattern(Member.Kind kind, ModifiersPattern modifiers,
public SignaturePattern(MemberKind kind, ModifiersPattern modifiers,
TypePattern returnType, TypePattern declaringType,
NamePattern name, TypePatternList parameterTypes,
ThrowsPattern throwsPattern,
@@ -596,7 +597,7 @@ public class SignaturePattern extends PatternNode {
public NamePattern getName() { return name; }
public TypePattern getDeclaringType() { return declaringType; }
public Member.Kind getKind() {
public MemberKind getKind() {
return kind;
}
@@ -682,7 +683,7 @@ public class SignaturePattern extends PatternNode {
}

public static SignaturePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
Member.Kind kind = Member.Kind.read(s);
MemberKind kind = MemberKind.read(s);
ModifiersPattern modifiers = ModifiersPattern.read(s);
TypePattern returnType = TypePattern.read(s, context);
TypePattern declaringType = TypePattern.read(s, context);

+ 5
- 4
weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java View File

@@ -15,6 +15,7 @@ import java.lang.reflect.Member;
import java.util.Iterator;

import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedType;
@@ -42,7 +43,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
* @param name
* @param parameterTypes
*/
public ReflectionBasedResolvedMemberImpl(Kind kind,
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers,
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes,
@@ -60,7 +61,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
* @param parameterTypes
* @param checkedExceptions
*/
public ReflectionBasedResolvedMemberImpl(Kind kind,
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers,
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions,
@@ -80,7 +81,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
* @param checkedExceptions
* @param backingGenericMember
*/
public ReflectionBasedResolvedMemberImpl(Kind kind,
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers,
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes,
@@ -99,7 +100,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
* @param name
* @param signature
*/
public ReflectionBasedResolvedMemberImpl(Kind kind,
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers, String name,
String signature, Member reflectMember) {
super(kind, declaringType, modifiers, name, signature);

+ 1
- 1
weaver/testsrc/org/aspectj/weaver/MemberTestCase.java View File

@@ -168,7 +168,7 @@ public class MemberTestCase extends TestCase {
private void declaringTypeTest(Member m, String declaringName) {
assertEquals(m + " declared in", UnresolvedType.forName(declaringName), m.getDeclaringType());
}
private void kindTest(Member m, MemberImpl.Kind kind) {
private void kindTest(Member m, MemberKind kind) {
assertEquals(m + " kind", kind, m.getKind());
}

Loading…
Cancel
Save