View | Details | Raw Unified | Return to bug 333274
Collapse All | Expand All

(-)src/org/aspectj/runtime/internal/AroundClosure.java (+5 lines)
Lines 73-76 Link Here
73
        this.bitflags = flags;
73
        this.bitflags = flags;
74
        return jp;
74
        return jp;
75
    }
75
    }
76
    
77
    public void unlink() {
78
        ProceedingJoinPoint jp = (ProceedingJoinPoint)state[state.length-1];
79
        jp.set$AroundClosure(null);
80
    }
76
}
81
}
(-)src/org/aspectj/runtime/reflect/JoinPointImpl.java (-8 / +15 lines)
Lines 13-18 Link Here
13
13
14
package org.aspectj.runtime.reflect;
14
package org.aspectj.runtime.reflect;
15
15
16
import java.util.Stack;
17
16
import org.aspectj.lang.JoinPoint;
18
import org.aspectj.lang.JoinPoint;
17
import org.aspectj.lang.ProceedingJoinPoint;
19
import org.aspectj.lang.ProceedingJoinPoint;
18
import org.aspectj.lang.Signature;
20
import org.aspectj.lang.Signature;
Lines 135-164 Link Here
135
	}
137
	}
136
138
137
	// To proceed we need a closure to proceed on
139
	// To proceed we need a closure to proceed on
138
	private AroundClosure arc;
140
	private Stack<AroundClosure> arcs = new Stack();
139
141
140
	public void set$AroundClosure(AroundClosure arc) {
142
	public void set$AroundClosure(AroundClosure arc) {
141
		this.arc = arc;
143
		// If arc is null this is the 'unset'
144
		if (arc==null) {
145
			this.arcs.pop();
146
		} else {
147
			this.arcs.push(arc);
148
		}
142
	}
149
	}
143
150
144
	public Object proceed() throws Throwable {
151
	public Object proceed() throws Throwable {
145
		// when called from a before advice, but be a no-op
152
		// when called from a before advice, but be a no-op
146
		if (arc == null)
153
		if (arcs.isEmpty())
147
			return null;
154
			return null;
148
		else
155
		else
149
			return arc.run(arc.getState());
156
			return arcs.peek().run(arcs.peek().getState());
150
	}
157
	}
151
158
152
	public Object proceed(Object[] adviceBindings) throws Throwable {
159
	public Object proceed(Object[] adviceBindings) throws Throwable {
153
		// when called from a before advice, but be a no-op
160
		// when called from a before advice, but be a no-op
154
		if (arc == null)
161
		if (arcs.isEmpty())
155
			return null;
162
			return null;
156
		else {
163
		else {
157
164
158
			// Based on the bit flags in the AroundClosure we can determine what to
165
			// Based on the bit flags in the AroundClosure we can determine what to
159
			// expect in the adviceBindings array. We may or may not be expecting
166
			// expect in the adviceBindings array. We may or may not be expecting
160
			// the first value to be a new this or a new target... (see pr126167)
167
			// the first value to be a new this or a new target... (see pr126167)
161
			int flags = arc.getFlags();
168
			int flags = arcs.peek().getFlags();
162
			boolean unset = (flags & 0x100000) != 0;
169
			boolean unset = (flags & 0x100000) != 0;
163
			boolean thisTargetTheSame = (flags & 0x010000) != 0;
170
			boolean thisTargetTheSame = (flags & 0x010000) != 0;
164
			boolean hasThis = (flags & 0x001000) != 0;
171
			boolean hasThis = (flags & 0x001000) != 0;
Lines 167-173 Link Here
167
			boolean bindsTarget = (flags & 0x000001) != 0;
174
			boolean bindsTarget = (flags & 0x000001) != 0;
168
175
169
			// state is always consistent with caller?,callee?,formals...,jp
176
			// state is always consistent with caller?,callee?,formals...,jp
170
			Object[] state = arc.getState();
177
			Object[] state = arcs.peek().getState();
171
178
172
			// these next two numbers can differ because some join points have a this and
179
			// these next two numbers can differ because some join points have a this and
173
			// target that are the same (eg. call) - and yet you can bind this and target
180
			// target that are the same (eg. call) - and yet you can bind this and target
Lines 218-224 Link Here
218
			// state[i] = adviceBindings[formalIndex];
225
			// state[i] = adviceBindings[formalIndex];
219
			// }
226
			// }
220
			// }
227
			// }
221
			return arc.run(state);
228
			return arcs.peek().run(state);
222
		}
229
		}
223
	}
230
	}
224
231
(-)src/org/aspectj/weaver/bcel/BcelShadow.java (+16 lines)
Lines 2890-2899 Link Here
2890
		if (bindsTarget(munger)) {
2890
		if (bindsTarget(munger)) {
2891
			bitflags |= 0x000001;
2891
			bitflags |= 0x000001;
2892
		}
2892
		}
2893
		
2894
		BcelVar aroundClosureInstance = null;
2893
2895
2894
		// ATAJ for @AJ aspect we need to link the closure with the joinpoint instance
2896
		// ATAJ for @AJ aspect we need to link the closure with the joinpoint instance
2895
		if (munger.getConcreteAspect() != null && munger.getConcreteAspect().isAnnotationStyleAspect()
2897
		if (munger.getConcreteAspect() != null && munger.getConcreteAspect().isAnnotationStyleAspect()
2896
				&& munger.getDeclaringAspect() != null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
2898
				&& munger.getDeclaringAspect() != null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
2899
2900
			aroundClosureInstance = genTempVar(AjcMemberMaker.AROUND_CLOSURE_TYPE);
2901
			closureInstantiation.append(fact.createDup(1));
2902
			aroundClosureInstance.appendStore(closureInstantiation, fact);
2903
			
2897
			// stick the bitflags on the stack and call the variant of linkClosureAndJoinPoint that takes an int
2904
			// stick the bitflags on the stack and call the variant of linkClosureAndJoinPoint that takes an int
2898
			closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags)));
2905
			closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags)));
2899
			closureInstantiation.append(Utility.createInvoke(getFactory(), getWorld(), new MemberImpl(Member.METHOD, UnresolvedType
2906
			closureInstantiation.append(Utility.createInvoke(getFactory(), getWorld(), new MemberImpl(Member.METHOD, UnresolvedType
Lines 2906-2911 Link Here
2906
2913
2907
		// invoke the advice
2914
		// invoke the advice
2908
		advice.append(munger.getNonTestAdviceInstructions(this));
2915
		advice.append(munger.getNonTestAdviceInstructions(this));
2916
		if (munger.getConcreteAspect() != null && munger.getConcreteAspect().isAnnotationStyleAspect()
2917
				&& munger.getDeclaringAspect() != null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
2918
			aroundClosureInstance.appendLoad(advice, fact);
2919
2920
			advice.append(Utility.createInvoke(getFactory(), getWorld(), new MemberImpl(Member.METHOD, UnresolvedType
2921
					.forName("org.aspectj.runtime.internal.AroundClosure"), Modifier.PUBLIC, "unlink",
2922
					"()V")));
2923
		}		
2924
		
2909
		advice.append(returnConversionCode);
2925
		advice.append(returnConversionCode);
2910
		if (getKind() == Shadow.MethodExecution && linenumber > 0) {
2926
		if (getKind() == Shadow.MethodExecution && linenumber > 0) {
2911
			advice.getStart().addTargeter(new LineNumberTag(linenumber));
2927
			advice.getStart().addTargeter(new LineNumberTag(linenumber));

Return to bug 333274