From fcb23bffb3725128f528a222adb92cd6e2719fd1 Mon Sep 17 00:00:00 2001 From: jhugunin Date: Tue, 31 Dec 2002 00:55:19 +0000 Subject: [PATCH] can't do around x initialization, refactored hasThis kinda thing --- weaver/src/org/aspectj/weaver/Advice.java | 7 +- weaver/src/org/aspectj/weaver/Shadow.java | 121 ++++++++++++++++-- .../aspectj/weaver/bcel/BcelClassWeaver.java | 11 +- .../org/aspectj/weaver/bcel/BcelShadow.java | 80 ++++++------ .../aspectj/weaver/bcel/ExceptionRange.java | 10 +- weaver/src/org/aspectj/weaver/bcel/Range.java | 4 + 6 files changed, 178 insertions(+), 55 deletions(-) diff --git a/weaver/src/org/aspectj/weaver/Advice.java b/weaver/src/org/aspectj/weaver/Advice.java index 361c4a93f..e903b6c42 100644 --- a/weaver/src/org/aspectj/weaver/Advice.java +++ b/weaver/src/org/aspectj/weaver/Advice.java @@ -104,10 +104,15 @@ public abstract class Advice extends ShadowMunger { return shadow.hasThis(); } else if (kind == AdviceKind.Around) { if (shadow.getKind() == Shadow.PreInitialization) { - world.showMessage(IMessage.WARNING, + world.showMessage(IMessage.ERROR, "around on pre-initialization not supported (compiler limitation)", getSourceLocation(), shadow.getSourceLocation()); return false; + } else if (shadow.getKind() == Shadow.Initialization) { + world.showMessage(IMessage.ERROR, + "around on initialization not supported (compiler limitation)", + getSourceLocation(), shadow.getSourceLocation()); + return false; } else { if (!getSignature().getReturnType().isConvertableFrom(shadow.getReturnType(), world)) { //System.err.println(this + ", " + sourceContext + ", " + start); diff --git a/weaver/src/org/aspectj/weaver/Shadow.java b/weaver/src/org/aspectj/weaver/Shadow.java index 105119420..6e37e89f3 100644 --- a/weaver/src/org/aspectj/weaver/Shadow.java +++ b/weaver/src/org/aspectj/weaver/Shadow.java @@ -35,29 +35,88 @@ import org.aspectj.util.*; public abstract class Shadow { private final Kind kind; private final Member signature; + protected final Shadow enclosingShadow; protected List mungers = new ArrayList(1); // ---- - - protected Shadow(Kind kind, Member signature) { + protected Shadow(Kind kind, Member signature, Shadow enclosingShadow) { this.kind = kind; this.signature = signature; + this.enclosingShadow = enclosingShadow; } // ---- public abstract World getIWorld(); + /** + * could this(*) pcd ever match + */ + public final boolean hasThis() { + if (getKind().neverHasThis()) { + return false; + } else if (getKind().isEnclosingKind()) { + return !getSignature().isStatic(); + } else if (enclosingShadow == null) { + return false; + } else { + return enclosingShadow.hasThis(); + } + } + + /** + * the type of the this object here + * + * @throws IllegalStateException if there is no this here + */ + public final TypeX getThisType() { + if (!hasThis()) throw new IllegalStateException("no this"); + if (getKind().isEnclosingKind()) { + return getSignature().getDeclaringType(); + } else { + return enclosingShadow.getThisType(); + } + } + + /** + * a var referencing this + * + * @throws IllegalStateException if there is no target here + */ + public abstract Var getThisVar(); + + + + /** + * could target(*) pcd ever match + */ public final boolean hasTarget() { - return !(getSignature().isStatic() || (getKind() == ConstructorCall) - || (getKind() == PreInitialization)); + if (getKind().neverHasTarget()) { + return false; + } else if (getKind().isTargetSameAsThis()) { + return hasThis(); + } else { + return !getSignature().isStatic(); + } } + /** + * the type of the target object here + * + * @throws IllegalStateException if there is no target here + */ public final TypeX getTargetType() { - if (!hasTarget()) return ResolvedTypeX.MISSING; + if (!hasTarget()) throw new IllegalStateException("no target"); return getSignature().getDeclaringType(); } + /** + * a var referencing the target + * + * @throws IllegalStateException if there is no target here + */ + public abstract Var getTargetVar(); + public TypeX[] getArgTypes() { if (getKind() == FieldSet) return new TypeX[] { getSignature().getReturnType() }; return getSignature().getParameterTypes(); @@ -73,12 +132,9 @@ public abstract class Shadow { return getSignature() .getParameterTypes().length; } - - public abstract boolean hasThis(); - public abstract TypeX getThisType(); + public abstract TypeX getEnclosingType(); - public abstract Var getThisVar(); - public abstract Var getTargetVar(); + public abstract Var getArgVar(int i); public abstract Var getThisJoinPointVar(); @@ -128,7 +184,7 @@ public abstract class Shadow { /** A type-safe enum representing the kind of shadows */ public static final class Kind extends TypeSafeEnum { - private boolean argsOnStack; + private boolean argsOnStack; //XXX unused public Kind(String name, int key, boolean argsOnStack) { super(name, key); @@ -140,7 +196,7 @@ public abstract class Shadow { } public boolean argsOnStack() { - return argsOnStack; + return !isTargetSameAsThis(); } // !!! this is false for handlers! @@ -148,6 +204,44 @@ public abstract class Shadow { return true; } + // XXX revisit along with removal of priorities + public boolean hasHighPriorityExceptions() { + return !isTargetSameAsThis(); + } + + + /** + * These are all the shadows that contains other shadows within them and + * are often directly associated with methods. + */ + public boolean isEnclosingKind() { + return this == MethodExecution || this == ConstructorExecution || + this == AdviceExecution || this == StaticInitialization + || this == Initialization; + } + + public boolean isTargetSameAsThis() { + return this == MethodExecution + || this == ConstructorExecution + || this == StaticInitialization + || this == PreInitialization + || this == AdviceExecution + || this == Initialization; + } + + public boolean neverHasTarget() { + return this == ConstructorCall + || this == ExceptionHandler + || this == PreInitialization + || this == StaticInitialization; + } + + public boolean neverHasThis() { + return this == PreInitialization + || this == StaticInitialization; + } + + public String getSimpleName() { int dash = getName().lastIndexOf('-'); if (dash == -1) return getName(); @@ -233,6 +327,9 @@ public abstract class Shadow { + + + // ---- type access methods diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index a56b7d139..8ceda85e3 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -495,6 +495,10 @@ class BcelClassWeaver implements IClassWeaver { (InstructionHandle) srcToDest.get(oldRange.getEnd())); shadowMap.put(oldRange, freshRange); //recipient.matchedShadows.add(freshShadow); + // XXX should go through the NEW copied shadow and update + // the thisVar, targetVar, and argsVar + // ??? Might want to also go through at this time and add + // "extra" vars to the shadow. } } } @@ -634,13 +638,16 @@ class BcelClassWeaver implements IClassWeaver { enclosingShadow = BcelShadow.makeConstructorExecution(world, mg, superOrThisCall); // walk the body + boolean beforeSuperOrThisCall = true; if (shouldWeaveBody(mg)) { //!mg.isAjSynthetic()) { for (InstructionHandle h = mg.getBody().getStart(); h != null; h = h.getNext()) { - if (h == superOrThisCall) + if (h == superOrThisCall) { + beforeSuperOrThisCall = false; continue; - match(mg, h, enclosingShadow, shadowAccumulator); + } + match(mg, h, beforeSuperOrThisCall ? null : enclosingShadow, shadowAccumulator); } match(enclosingShadow, shadowAccumulator); } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java index 8fad558e1..4f80060e1 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java @@ -78,9 +78,7 @@ public class BcelShadow extends Shadow { private ShadowRange range; private final BcelWorld world; private final LazyMethodGen enclosingMethod; - private final BcelShadow enclosingShadow; - - private boolean fallsThrough; + private boolean fallsThrough; //XXX not used anymore // ---- initialization @@ -96,10 +94,9 @@ public class BcelShadow extends Shadow { LazyMethodGen enclosingMethod, BcelShadow enclosingShadow) { - super(kind, signature); + super(kind, signature, enclosingShadow); this.world = world; this.enclosingMethod = enclosingMethod; - this.enclosingShadow = enclosingShadow; fallsThrough = kind.argsOnStack(); } @@ -273,7 +270,7 @@ public class BcelShadow extends Shadow { // overrides public TypeX getEnclosingType() { - return world.resolve(getEnclosingClass().getClassName()); + return getEnclosingClass().getType(); } public LazyClassGen getEnclosingClass() { @@ -652,23 +649,6 @@ public class BcelShadow extends Shadow { } // ---- type access methods - - public boolean hasThis() { - if (getKind() == PreInitialization) return false; - return !getEnclosingCodeSignature().isStatic(); - //???return !enclosingMethod.isStatic(); - } - public TypeX getThisType() { - if (!hasThis()) return ResolvedTypeX.MISSING; - return getEnclosingCodeSignature().getDeclaringType(); - //???return TypeX.forName(getEnclosingClass().getClassName()); - } - - public boolean isTargetDifferentFromThis() { - return hasTarget() && isExpressionKind(); - } - - private ObjectType getTargetBcelType() { return (ObjectType) world.makeBcelType(getTargetType()); } @@ -677,10 +657,28 @@ public class BcelShadow extends Shadow { } // ---- kinding + + /** + * If the end of my range has no real instructions following then + * my context needs a return at the end. + */ + public boolean terminatesWithReturn() { + return getRange().getRealNext() == null; + } - public boolean isExpressionKind() { - if (getKind() == PreInitialization) return true; - return getKind().argsOnStack(); + /** + * Is arg0 occupied with the value of this + */ + public boolean arg0HoldsThis() { + if (getKind().isEnclosingKind()) { + return !getSignature().isStatic(); + } else if (enclosingShadow == null) { + //XXX this is mostly right + // this doesn't do the right thing for calls in the pre part of introduced constructors. + return !enclosingMethod.isStatic(); + } else { + return ((BcelShadow)enclosingShadow).arg0HoldsThis(); + } } // ---- argument getting methods @@ -770,7 +768,7 @@ public class BcelShadow extends Shadow { // the enclosing of an execution is itself return getThisJoinPointStaticPartBcelVar(); } else { - return enclosingShadow.getThisJoinPointStaticPartBcelVar(); + return ((BcelShadow)enclosingShadow).getThisJoinPointStaticPartBcelVar(); } } @@ -815,8 +813,8 @@ public class BcelShadow extends Shadow { public void initializeTargetVar() { InstructionFactory fact = getFactory(); if (targetVar != null) return; - if (! isExpressionKind()) { - initializeThisVar(); + if (getKind().isTargetSameAsThis()) { + if (hasThis()) initializeThisVar(); targetVar = thisVar; } else { initializeArgVars(); // gotta pop off the args before we find the target @@ -846,7 +844,7 @@ public class BcelShadow extends Shadow { } } else { int index = 0; - if (hasThis()) index++; + if (arg0HoldsThis()) index++; for (int i = 0; i < len; i++) { TypeX type = getArgType(i); @@ -966,7 +964,7 @@ public class BcelShadow extends Shadow { enclosingMethod.addExceptionHandler(range.getStart().getNext(), protectedEnd.getPrev(), handlerStart, (ObjectType)BcelWorld.makeBcelType(catchType), //???Type.THROWABLE, // high priority if our args are on the stack - isExpressionKind()); + getKind().hasHighPriorityExceptions()); } @@ -994,7 +992,7 @@ public class BcelShadow extends Shadow { enclosingMethod.addExceptionHandler(range.getStart().getNext(), protectedEnd.getPrev(), handlerStart, (ObjectType)BcelWorld.makeBcelType(catchType), // high priority if our args are on the stack - isExpressionKind()); + getKind().hasHighPriorityExceptions()); } @@ -1173,7 +1171,7 @@ public class BcelShadow extends Shadow { range.append(advice); } else { InstructionList callback = makeCallToCallback(extractedMethod); - if (! isExpressionKind()) { + if (terminatesWithReturn()) { callback.append(fact.createReturn(extractedMethod.getReturnType())); } else { advice.append(fact.createBranchInstruction(Constants.GOTO, range.getEnd())); @@ -1358,7 +1356,7 @@ public class BcelShadow extends Shadow { } else { InstructionList callback = makeCallToCallback(callbackMethod); InstructionList postCallback = new InstructionList(); - if (! isExpressionKind()) { + if (terminatesWithReturn()) { callback.append(fact.createReturn(callbackMethod.getReturnType())); } else { advice.append(fact.createBranchInstruction(Constants.GOTO, postCallback.append(fact.NOP))); @@ -1652,7 +1650,7 @@ public class BcelShadow extends Shadow { int newi = 0; // if we're passing in a this and we're not argsOnStack we're always // passing in a target too - if (hasThis()) { ret.put(0, 0); oldi++; newi+=1; } + if (arg0HoldsThis()) { ret.put(0, 0); oldi++; newi+=1; } //assert targetVar == thisVar for (int i = 0; i < getArgCount(); i++) { TypeX type = getArgType(i); @@ -1661,6 +1659,12 @@ public class BcelShadow extends Shadow { newi += type.getSize(); } } + +// System.err.println("making remap for : " + this); +// if (targetVar != null) System.err.println("target slot : " + targetVar.getSlot()); +// if (thisVar != null) System.err.println(" this slot : " + thisVar.getSlot()); +// System.err.println(ret); + return ret; } @@ -1684,7 +1688,7 @@ public class BcelShadow extends Shadow { TypeX targetType = getTargetType(); ResolvedMember resolvedMember = getSignature().resolve(world); if (resolvedMember != null && Modifier.isProtected(resolvedMember.getModifiers()) && - !samePackage(targetType.getPackageName(), getThisType().getPackageName())) + !samePackage(targetType.getPackageName(), getEnclosingType().getPackageName())) { if (!targetType.isAssignableFrom(getThisType(), world)) { throw new BCException("bad bytecode"); @@ -1777,7 +1781,7 @@ public class BcelShadow extends Shadow { return new SourceLocation(new File(getEnclosingClass().getFileName()), getSourceLine()); } - public BcelShadow getEnclosingShadow() { + public Shadow getEnclosingShadow() { return enclosingShadow; } @@ -1786,6 +1790,6 @@ public class BcelShadow extends Shadow { } public boolean isFallsThrough() { - return fallsThrough; + return !terminatesWithReturn(); //fallsThrough; } } diff --git a/weaver/src/org/aspectj/weaver/bcel/ExceptionRange.java b/weaver/src/org/aspectj/weaver/bcel/ExceptionRange.java index 2e6520361..a18bf8f45 100644 --- a/weaver/src/org/aspectj/weaver/bcel/ExceptionRange.java +++ b/weaver/src/org/aspectj/weaver/bcel/ExceptionRange.java @@ -42,14 +42,20 @@ public final class ExceptionRange extends Range { /** * After this constructor is called, this range is not well situated unless * {@link #associateWithTargets} is called + * + * XXX priority should be fixed */ public ExceptionRange(InstructionList body, TypeX exceptionType, int priority) { super(body); this.exceptionType = exceptionType; this.priority = priority; } - public ExceptionRange(InstructionList body, TypeX exceptionType, boolean highPriority) { - this(body, exceptionType, highPriority ? Integer.MAX_VALUE : -1); + + /** + * @param insideExisting + */ + public ExceptionRange(InstructionList body, TypeX exceptionType, boolean insideExisting) { + this(body, exceptionType, insideExisting ? Integer.MAX_VALUE : -1); } public void associateWithTargets( InstructionHandle start, diff --git a/weaver/src/org/aspectj/weaver/bcel/Range.java b/weaver/src/org/aspectj/weaver/bcel/Range.java index 49df80897..416c02a77 100644 --- a/weaver/src/org/aspectj/weaver/bcel/Range.java +++ b/weaver/src/org/aspectj/weaver/bcel/Range.java @@ -80,6 +80,10 @@ abstract class Range implements InstructionTargeter { return getRealEnd(end); } + InstructionHandle getRealNext() { + return getRealStart(end); + } + static InstructionHandle getRealPrev(InstructionHandle ih) { InstructionHandle ret = ih.getPrev(); while (isRangeHandle(ret)) { -- 2.39.5