@@ -359,6 +359,8 @@ public class BuildArgParser extends org.eclipse.jdt.internal.compiler.batch.Main | |||
buildConfig.setNoWeave(true); | |||
} else if (arg.equals("-XserializableAspects")) { | |||
buildConfig.setXserializableAspects(true); | |||
} else if (arg.equals("-XnoInline")) { | |||
buildConfig.setXnoInline(true); | |||
} else if (arg.equals("-Xlintfile")) { | |||
if (args.size() > nextArgIndex) { | |||
File lintSpecFile = makeFile(((ConfigParser.Arg)args.get(nextArgIndex)).getValue()); |
@@ -0,0 +1,114 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Common Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/cpl-v10.html | |||
* | |||
* Contributors: | |||
* Xerox/PARC initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.ajdt.internal.compiler.ast; | |||
import java.util.Arrays; | |||
import org.aspectj.ajdt.internal.compiler.lookup.*; | |||
import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler; | |||
import org.aspectj.weaver.*; | |||
import org.aspectj.weaver.ShadowMunger; | |||
import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter; | |||
import org.eclipse.jdt.internal.compiler.ast.*; | |||
import org.eclipse.jdt.internal.compiler.lookup.*; | |||
/** | |||
* Takes a method that already has the three extra parameters | |||
* thisJoinPointStaticPart, thisJoinPoint and thisEnclosingJoinPointStaticPart | |||
*/ | |||
public class AccessForInlineVisitor extends AbstractSyntaxTreeVisitorAdapter { | |||
PrivilegedHandler handler; | |||
EclipseWorld world; | |||
public AccessForInlineVisitor(EclipseWorld world, PrivilegedHandler handler) { | |||
this.world = world; | |||
this.handler = handler; | |||
} | |||
public void endVisit(SingleNameReference ref, BlockScope scope) { | |||
if (ref.binding instanceof FieldBinding) { | |||
FieldBinding fieldBinding = (FieldBinding)ref.binding; | |||
makePublic(fieldBinding.declaringClass); | |||
if (isPublic(fieldBinding)) return; | |||
ref.binding = handler.getPrivilegedAccessField(fieldBinding); | |||
} | |||
} | |||
public void endVisit(QualifiedNameReference ref, BlockScope scope) { | |||
if (ref.binding instanceof FieldBinding) { | |||
FieldBinding fieldBinding = (FieldBinding)ref.binding; | |||
makePublic(fieldBinding.declaringClass); | |||
if (isPublic(fieldBinding)) return; | |||
ref.binding = handler.getPrivilegedAccessField(fieldBinding); | |||
} | |||
} | |||
public void endVisit(FieldReference ref, BlockScope scope) { | |||
if (ref.binding instanceof FieldBinding) { | |||
FieldBinding fieldBinding = (FieldBinding)ref.binding; | |||
makePublic(fieldBinding.declaringClass); | |||
if (isPublic(fieldBinding)) return; | |||
ref.binding = handler.getPrivilegedAccessField(fieldBinding); | |||
} | |||
} | |||
public void endVisit(MessageSend send, BlockScope scope) { | |||
if (send instanceof Proceed) return; | |||
if (send.binding == null) return; | |||
if (isPublic(send.binding)) return; | |||
makePublic(send.binding.declaringClass); | |||
send.binding = send.codegenBinding = handler.getPrivilegedAccessMethod(send.binding); | |||
} | |||
public void endVisit(AllocationExpression send, BlockScope scope) { | |||
if (send.binding == null) return; | |||
if (isPublic(send.binding)) return; | |||
makePublic(send.binding.declaringClass); | |||
send.binding = handler.getPrivilegedAccessMethod(send.binding); | |||
} | |||
public void endVisit( | |||
QualifiedTypeReference ref, | |||
BlockScope scope) | |||
{ | |||
makePublic(ref.binding); | |||
} | |||
public void endVisit( | |||
SingleTypeReference ref, | |||
BlockScope scope) | |||
{ | |||
makePublic(ref.binding); | |||
} | |||
private boolean isPublic(FieldBinding fieldBinding) { | |||
// these are always effectively public to the inliner | |||
if (fieldBinding instanceof InterTypeFieldBinding) return true; | |||
return fieldBinding.isPublic(); | |||
} | |||
private boolean isPublic(MethodBinding methodBinding) { | |||
// these are always effectively public to the inliner | |||
if (methodBinding instanceof InterTypeMethodBinding) return true; | |||
return methodBinding.isPublic(); | |||
} | |||
private void makePublic(TypeBinding binding) { | |||
if (binding instanceof ReferenceBinding) { | |||
ReferenceBinding rb = (ReferenceBinding)binding; | |||
if (!rb.isPublic()) handler.notePrivilegedTypeAccess(rb); | |||
} else if (binding instanceof ArrayBinding) { | |||
makePublic( ((ArrayBinding)binding).leafComponentType ); | |||
} else { | |||
return; | |||
} | |||
} | |||
} |
@@ -47,6 +47,8 @@ public class AdviceDeclaration extends MethodDeclaration { | |||
public MethodBinding proceedMethodBinding; | |||
public List proceedCalls = new ArrayList(2); | |||
public boolean proceedInInners; | |||
public ResolvedMember[] proceedCallSignatures; | |||
public boolean[] formalsUnchangedToProceed; | |||
@@ -98,15 +100,9 @@ public class AdviceDeclaration extends MethodDeclaration { | |||
pointcutDesignator.finishResolveTypes(this, this.binding, | |||
baseArgumentCount, upperScope.referenceContext.binding); | |||
if (binding == null || ignoreFurtherInvestigation) return; | |||
if (kind == AdviceKind.Around && binding != null) { | |||
//XXX set these correctly | |||
proceedInInners = false; | |||
proceedCallSignatures = new ResolvedMember[0]; | |||
formalsUnchangedToProceed = new boolean[baseArgumentCount]; | |||
declaredExceptions = new TypeX[0]; | |||
if (kind == AdviceKind.Around) { | |||
ReferenceBinding[] exceptions = | |||
new ReferenceBinding[] { upperScope.getJavaLangThrowable() }; | |||
proceedMethodBinding = new MethodBinding(Modifier.STATIC, | |||
@@ -119,6 +115,44 @@ public class AdviceDeclaration extends MethodDeclaration { | |||
super.resolveStatements(upperScope); | |||
if (binding != null) determineExtraArgumentFlags(); | |||
if (kind == AdviceKind.Around) { | |||
int n = proceedCalls.size(); | |||
EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(upperScope); | |||
//System.err.println("access to: " + Arrays.asList(handler.getMembers())); | |||
//XXX set these correctly | |||
formalsUnchangedToProceed = new boolean[baseArgumentCount]; | |||
proceedCallSignatures = new ResolvedMember[0]; | |||
proceedInInners = false; | |||
declaredExceptions = new TypeX[0]; | |||
for (int i=0; i < n; i++) { | |||
Proceed call = (Proceed)proceedCalls.get(i); | |||
if (call.inInner) { | |||
//System.err.println("proceed in inner: " + call); | |||
proceedInInners = true; | |||
//XXX wrong | |||
//proceedCallSignatures[i] = world.makeResolvedMember(call.binding); | |||
} | |||
} | |||
// if we have proceed in inners we won't ever be inlined so the code below is unneeded | |||
if (!proceedInInners) { | |||
PrivilegedHandler handler = (PrivilegedHandler)upperScope.referenceContext.binding.privilegedHandler; | |||
//XXX timings is odd here | |||
if (handler == null) { | |||
handler = new PrivilegedHandler((AspectDeclaration)upperScope.referenceContext); | |||
upperScope.referenceContext.binding.privilegedHandler = handler; | |||
} | |||
this.traverse(new MakeDeclsPublicVisitor(), (ClassScope)null); | |||
AccessForInlineVisitor v = new AccessForInlineVisitor(world, handler); | |||
this.traverse(v, (ClassScope) null); | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,57 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Common Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/cpl-v10.html | |||
* | |||
* Contributors: | |||
* Xerox/PARC initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.ajdt.internal.compiler.ast; | |||
import java.util.Arrays; | |||
import org.aspectj.ajdt.internal.compiler.lookup.*; | |||
import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler; | |||
import org.aspectj.weaver.*; | |||
import org.aspectj.weaver.ShadowMunger; | |||
import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter; | |||
import org.eclipse.jdt.internal.compiler.ast.*; | |||
import org.eclipse.jdt.internal.compiler.lookup.*; | |||
/** | |||
* Takes a method that already has the three extra parameters | |||
* thisJoinPointStaticPart, thisJoinPoint and thisEnclosingJoinPointStaticPart | |||
*/ | |||
public class MakeDeclsPublicVisitor extends AbstractSyntaxTreeVisitorAdapter { | |||
public void endVisit( | |||
AnonymousLocalTypeDeclaration decl, | |||
BlockScope scope) { | |||
decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers); | |||
} | |||
public void endVisit(LocalTypeDeclaration decl, BlockScope scope) { | |||
decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers); | |||
} | |||
public void endVisit(ConstructorDeclaration decl, ClassScope scope) { | |||
decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers); | |||
} | |||
public void endVisit(FieldDeclaration decl, MethodScope scope) { | |||
decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers); | |||
} | |||
public void endVisit(MethodDeclaration decl, ClassScope scope) { | |||
decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers); | |||
} | |||
} |
@@ -22,6 +22,8 @@ import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; | |||
public class Proceed extends MessageSend { | |||
public boolean inInner = false; | |||
public Proceed(MessageSend parent) { | |||
super(); | |||
@@ -108,11 +110,14 @@ public class Proceed extends MessageSend { | |||
if (context instanceof AdviceDeclaration) { | |||
AdviceDeclaration adviceDecl = (AdviceDeclaration)context; | |||
if (adviceDecl.kind == AdviceKind.Around) { | |||
adviceDecl.proceedCalls.add(this); | |||
return adviceDecl; | |||
} else { | |||
return null; | |||
} | |||
} | |||
} else if (scope instanceof ClassScope) { | |||
inInner = true; | |||
} | |||
return findEnclosingAround(scope.parent); |
@@ -0,0 +1,224 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Common Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/cpl-v10.html | |||
* | |||
* Contributors: | |||
* Xerox/PARC initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.ajdt.internal.compiler.ast; | |||
import java.util.Arrays; | |||
import org.aspectj.weaver.*; | |||
import org.aspectj.weaver.ShadowMunger; | |||
import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter; | |||
import org.eclipse.jdt.internal.compiler.ast.*; | |||
import org.eclipse.jdt.internal.compiler.lookup.*; | |||
/** | |||
* Takes a method that already has the three extra parameters | |||
* thisJoinPointStaticPart, thisJoinPoint and thisEnclosingJoinPointStaticPart | |||
*/ | |||
public class ProceedVisitor extends AbstractSyntaxTreeVisitorAdapter { | |||
boolean needsDynamic = false; | |||
boolean needsStatic = false; | |||
boolean needsStaticEnclosing = false; | |||
boolean hasEffectivelyStaticRef = false; | |||
LocalVariableBinding thisJoinPointDec; | |||
LocalVariableBinding thisJoinPointStaticPartDec; | |||
LocalVariableBinding thisEnclosingJoinPointStaticPartDec; | |||
LocalVariableBinding thisJoinPointDecLocal; | |||
LocalVariableBinding thisJoinPointStaticPartDecLocal; | |||
LocalVariableBinding thisEnclosingJoinPointStaticPartDecLocal; | |||
boolean replaceEffectivelyStaticRefs = false; | |||
AbstractMethodDeclaration method; | |||
ProceedVisitor(AbstractMethodDeclaration method) { | |||
this.method = method; | |||
int index = method.arguments.length - 3; | |||
thisJoinPointStaticPartDecLocal = method.scope.locals[index]; | |||
thisJoinPointStaticPartDec = method.arguments[index++].binding; | |||
thisJoinPointDecLocal = method.scope.locals[index]; | |||
thisJoinPointDec = method.arguments[index++].binding; | |||
thisEnclosingJoinPointStaticPartDecLocal = method.scope.locals[index]; | |||
thisEnclosingJoinPointStaticPartDec = method.arguments[index++].binding; | |||
} | |||
public void computeJoinPointParams() { | |||
// walk my body to see what is needed | |||
method.traverse(this, (ClassScope) null); | |||
//??? add support for option to disable this optimization | |||
//System.err.println("check: "+ hasEffectivelyStaticRef + ", " + needsDynamic); | |||
if (hasEffectivelyStaticRef && !needsDynamic) { | |||
// replace effectively static refs with thisJoinPointStaticPart | |||
replaceEffectivelyStaticRefs = true; | |||
needsStatic = true; | |||
method.traverse(this, (ClassScope) null); | |||
} | |||
} | |||
boolean isRef(NameReference ref, Binding binding) { | |||
return ref.binding == binding; | |||
} | |||
boolean isRef(Expression expr, Binding binding) { | |||
//System.err.println("isRef: " + expr + ", " + binding); | |||
return expr != null | |||
&& expr instanceof NameReference | |||
&& isRef((NameReference) expr, binding); | |||
} | |||
public void endVisit(SingleNameReference ref, BlockScope scope) { | |||
if (isRef(ref, thisJoinPointDec)) | |||
needsDynamic = true; | |||
else if (isRef(ref, thisJoinPointStaticPartDec)) | |||
needsStatic = true; | |||
else if (isRef(ref, thisEnclosingJoinPointStaticPartDec)) | |||
needsStaticEnclosing = true; | |||
} | |||
// public void checkAndFix(ASTObject body) { | |||
// this.process(body); | |||
// if (needsFakeStatic && !needsDynamic) { | |||
// if (!this.getCompiler().getOptions().noMetaJoinPointOptimization) { | |||
// makeFakeStatics = true; | |||
// needsStatic = true; | |||
// this.process(body); | |||
// } else { | |||
// needsDynamic = true; | |||
// } | |||
// } | |||
// } | |||
boolean canTreatAsStatic(String id) { | |||
return id.equals("toString") | |||
|| id.equals("toShortString") | |||
|| id.equals("toLongString") | |||
|| id.equals("getKind") | |||
|| id.equals("getSignature") | |||
|| id.equals("getSourceLocation") | |||
|| id.equals("getStaticPart"); | |||
} | |||
// boolean canTreatAsStatic(VarExpr varExpr) { | |||
// ASTObject parent = varExpr.getParent(); | |||
// if (parent instanceof CallExpr) { | |||
// Method calledMethod = ((CallExpr)parent).getMethod(); | |||
// return canTreatAsStatic(calledMethod); | |||
// | |||
// //??? should add a case here to catch | |||
// //??? tjp.getEnclosingExecutionJoinPoint().STATIC_METHOD() | |||
// } else if (parent instanceof BinopExpr) { | |||
// BinopExpr binop = (BinopExpr)parent; | |||
// if (binop.getType().isEquivalent(this.getTypeManager().getStringType())) { | |||
// return true; | |||
// } else { | |||
// return false; | |||
// } | |||
// } else { | |||
// return false; | |||
// } | |||
// } | |||
boolean inBlockThatCantRun = false; | |||
public boolean visit(MessageSend call, BlockScope scope) { | |||
Expression receiver = call.receiver; | |||
if (isRef(receiver, thisJoinPointDec)) { | |||
if (canTreatAsStatic(new String(call.selector))) { | |||
if (replaceEffectivelyStaticRefs) { | |||
replaceEffectivelyStaticRef(call); | |||
} else { | |||
//System.err.println("has static reg"); | |||
hasEffectivelyStaticRef = true; | |||
if (call.arguments != null) { | |||
int argumentsLength = call.arguments.length; | |||
for (int i = 0; i < argumentsLength; i++) | |||
call.arguments[i].traverse(this, scope); | |||
} | |||
return false; | |||
} | |||
} | |||
} | |||
return super.visit(call, scope); | |||
} | |||
private void replaceEffectivelyStaticRef(MessageSend call) { | |||
//System.err.println("replace static ref"); | |||
NameReference receiver = (NameReference) call.receiver; | |||
receiver.binding = thisJoinPointStaticPartDecLocal; //thisJoinPointStaticPartDec; | |||
receiver.codegenBinding = thisJoinPointStaticPartDecLocal; | |||
call.binding.declaringClass = | |||
(ReferenceBinding) thisJoinPointStaticPartDec.type; | |||
} | |||
public int removeUnusedExtraArguments() { | |||
int extraArgumentFlags = 0; | |||
this.computeJoinPointParams(); | |||
MethodBinding binding = method.binding; | |||
int index = binding.parameters.length - 3; | |||
if (needsStaticEnclosing) { | |||
extraArgumentFlags |= Advice.ThisEnclosingJoinPointStaticPart; | |||
} else { | |||
removeParameter(index+2); | |||
} | |||
if (needsDynamic) { | |||
extraArgumentFlags |= Advice.ThisJoinPoint; | |||
} else { | |||
removeParameter(index+1); | |||
} | |||
if (needsStatic) { | |||
extraArgumentFlags |= Advice.ThisJoinPointStaticPart; | |||
} else { | |||
removeParameter(index+0); | |||
} | |||
return extraArgumentFlags; | |||
} | |||
private void removeParameter(int indexToRemove) { | |||
TypeBinding[] parameters = method.binding.parameters; | |||
method.scope.locals = removeLocalBinding(indexToRemove, method.scope.locals); | |||
method.binding.parameters = removeParameter(indexToRemove, method.binding.parameters); | |||
} | |||
private static TypeBinding[] removeParameter(int index, TypeBinding[] bindings) { | |||
int len = bindings.length; | |||
TypeBinding[] ret = new TypeBinding[len-1]; | |||
System.arraycopy(bindings, 0, ret, 0, index); | |||
System.arraycopy(bindings, index+1, ret, index, len-index-1); | |||
return ret; | |||
} | |||
private static LocalVariableBinding[] removeLocalBinding(int index, LocalVariableBinding[] bindings) { | |||
int len = bindings.length; | |||
//??? for performance we should do this in-place | |||
LocalVariableBinding[] ret = new LocalVariableBinding[len-1]; | |||
System.arraycopy(bindings, 0, ret, 0, index); | |||
System.arraycopy(bindings, index+1, ret, index, len-index-1); | |||
return ret; | |||
} | |||
} |
@@ -40,6 +40,7 @@ public class AjBuildConfig { | |||
private boolean emacsSymMode = false; | |||
private boolean noWeave = false; | |||
private boolean XserializableAspects = false; | |||
private boolean XnoInline = false; | |||
private String lintMode = AJLINT_DEFAULT; | |||
private File lintSpecFile = null; | |||
@@ -202,4 +203,12 @@ public class AjBuildConfig { | |||
XserializableAspects = xserializableAspects; | |||
} | |||
public boolean isXnoInline() { | |||
return XnoInline; | |||
} | |||
public void setXnoInline(boolean xnoInline) { | |||
XnoInline = xnoInline; | |||
} | |||
} |
@@ -239,6 +239,7 @@ public class AjBuildManager { | |||
private void initBcelWorld(IMessageHandler handler) throws IOException { | |||
bcelWorld = new BcelWorld(buildConfig.getClasspath(), handler); | |||
bcelWorld.setXnoInline(buildConfig.isXnoInline()); | |||
bcelWeaver = new BcelWeaver(bcelWorld); | |||
for (Iterator i = buildConfig.getAspectpath().iterator(); i.hasNext();) { | |||
@@ -504,6 +505,7 @@ public class AjBuildManager { | |||
pr, nameEnvironment); | |||
EclipseWorld ew = new EclipseWorld(le, handler); | |||
ew.setLint(bcelWorld.getLint()); | |||
ew.setXnoInline(buildConfig.isXnoInline()); | |||
le.world = ew; | |||
pr.world = ew; | |||
le.world.buildManager = this; |
@@ -21,8 +21,8 @@ import org.aspectj.testing.util.TestUtil; | |||
public class WorkingTestMain { | |||
public static void main(String[] args1) throws IOException { | |||
testExamples(); | |||
//testOne(); | |||
//testExamples(); | |||
testOne(); | |||
} | |||
public static void testOne() throws IOException { | |||
@@ -50,7 +50,8 @@ public class WorkingTestMain { | |||
//args.add("../weaver/testdata/megatrace.jar"); | |||
args.add("testdata/src1/AroundA1.java"); | |||
//args.add("../tests/new/AroundInnerCalls.java"); | |||
args.add("-XnoInline"); | |||
//args.add("../tests/new/Counting1.java"); | |||
//args.add("-Xlint:error"); | |||
//args.add("testdata/src1/InterType.java"); | |||
//args.add("@" + examplesDir + "tjp/files.lst"); | |||
@@ -59,12 +60,11 @@ public class WorkingTestMain { | |||
CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS); | |||
//CommandTestCase.runCompiler(args, new int[] {11, 14, 18, 32, 43}); | |||
// CommandTestCase.printGenerated("../out", "AdviceOnInheritedMethod"); | |||
CommandTestCase.printGenerated("../out", "AroundA1"); | |||
// CommandTestCase.printGenerated("../out", "SuperC"); | |||
// CommandTestCase.printGenerated("../out", "SubC"); | |||
//TestUtil.runMain("out;../bcweaver/testdata/megatrace.jar", "Privileged"); | |||
//TestUtil.runMain("out;../lib/test/testing-client.jar", "AroundInnerCalls"); | |||
TestUtil.runMain("out;../lib/test/testing-client.jar", "AroundA1"); | |||
} | |||
private static String examplesDir = "../docs/dist/doc/examples/"; |
@@ -21,7 +21,7 @@ import org.aspectj.weaver.patterns.*; | |||
public abstract class Advice extends ShadowMunger { | |||
AjAttribute.AdviceAttribute attribute; // the pointcut field is ignored | |||
protected AjAttribute.AdviceAttribute attribute; // the pointcut field is ignored | |||
protected AdviceKind kind; // alias of attribute.getKind() | |||
protected Member signature; |
@@ -27,6 +27,10 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab | |||
//public abstract boolean munge(LazyClassGen gen); | |||
/** returns null for mungers that are used internally, but were not part of a declared | |||
* thing in source code. | |||
*/ | |||
public ResolvedTypeMunger getMunger() { | |||
return munger; | |||
} |
@@ -45,7 +45,9 @@ public abstract class ResolvedTypeMunger { | |||
public boolean matches(ResolvedTypeX matchType) { | |||
ResolvedTypeX onType = matchType.getWorld().resolve(signature.getDeclaringType()); | |||
//System.err.println("matching: " + this + " to " + matchType + " onType = " + onType); | |||
if (matchType.equals(onType)) return true; | |||
//System.err.println("NO MATCH DIRECT"); | |||
if (onType.isInterface()) { | |||
return matchType.isTopmostImplementor(onType); |
@@ -33,7 +33,6 @@ public abstract class ResolvedTypeX extends TypeX { | |||
// ---- things that don't require a world | |||
/** returns Iterator<ResolvedTypeX> | |||
*/ | |||
public final Iterator getDirectSupertypes() { | |||
@@ -808,7 +807,9 @@ public abstract class ResolvedTypeX extends TypeX { | |||
public void addInterTypeMunger(ConcreteTypeMunger munger) { | |||
ResolvedMember sig = munger.getSignature(); | |||
if (sig == null) { | |||
if (sig == null || munger.getMunger() == null || | |||
munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) | |||
{ | |||
interTypeMungers.add(munger); | |||
return; | |||
} |
@@ -31,6 +31,8 @@ public abstract class World { | |||
protected StructureModel model = null; | |||
protected Lint lint = new Lint(this); | |||
protected boolean XnoInline; | |||
protected World() { | |||
super(); | |||
@@ -337,4 +339,12 @@ public abstract class World { | |||
this.lint = lint; | |||
} | |||
public boolean isXnoInline() { | |||
return XnoInline; | |||
} | |||
public void setXnoInline(boolean xnoInline) { | |||
XnoInline = xnoInline; | |||
} | |||
} |
@@ -85,6 +85,17 @@ public class BcelAdvice extends Advice { | |||
} | |||
} | |||
private boolean canInline(Shadow s) { | |||
if (attribute.isProceedInInners()) return false; | |||
//XXX this guard seems to only be needed for bad test cases | |||
if (concreteAspect == null || concreteAspect == ResolvedTypeX.MISSING) return false; | |||
if (concreteAspect.getWorld().isXnoInline()) return false; | |||
//System.err.println("isWoven? " + ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState()); | |||
return ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState() | |||
== WeaverStateKind.Woven; | |||
} | |||
public void implementOn(Shadow s) { | |||
BcelShadow shadow = (BcelShadow) s; | |||
if (getKind() == AdviceKind.Before) { | |||
@@ -100,8 +111,11 @@ public class BcelAdvice extends Advice { | |||
} else if (getKind() == AdviceKind.After) { | |||
shadow.weaveAfter(this); | |||
} else if (getKind() == AdviceKind.Around) { | |||
shadow.weaveAroundClosure(this, hasDynamicTests()); | |||
//shadow.weaveAroundInline(this, hasDynamicTests()); | |||
if (!canInline(s)) { | |||
shadow.weaveAroundClosure(this, hasDynamicTests()); | |||
} else { | |||
shadow.weaveAroundInline(this, hasDynamicTests()); | |||
} | |||
} else if (getKind() == AdviceKind.InterInitializer) { | |||
shadow.weaveAfterReturning(this); | |||
} else if (getKind().isCflow()) { |
@@ -33,6 +33,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
List typeMungers) | |||
{ | |||
boolean b = new BcelClassWeaver(world, clazz, shadowMungers, typeMungers).weave(); | |||
//System.err.println(clazz.getClassName() + ", " + clazz.getWeaverState()); | |||
//clazz.print(); | |||
return b; | |||
} |
@@ -1134,6 +1134,20 @@ public class BcelShadow extends Shadow { | |||
* If only one call to proceed is made, we can re-inline the original shadow. | |||
* We are not doing that presently. | |||
*/ | |||
// !!! THIS BLOCK OF CODE SHOULD BE IN A METHOD CALLED weaveAround(...); | |||
Member mungerSig = munger.getSignature(); | |||
ResolvedTypeX declaringType = world.resolve(mungerSig.getDeclaringType()); | |||
//??? might want some checks here to give better errors | |||
BcelObjectType ot = (BcelObjectType)declaringType; | |||
LazyMethodGen adviceMethod = ot.getLazyClassGen().getLazyMethodGen(mungerSig); | |||
if (!adviceMethod.getCanInline()) { | |||
weaveAroundClosure(munger, hasDynamicTest); | |||
return; | |||
} | |||
// start by exposing various useful things into the frame | |||
final InstructionFactory fact = getFactory(); | |||
@@ -1174,22 +1188,22 @@ public class BcelShadow extends Shadow { | |||
if (! hasDynamicTest) { | |||
range.append(advice); | |||
} else { | |||
InstructionList afterThingie = new InstructionList(fact.NOP); | |||
InstructionList callback = makeCallToCallback(extractedMethod); | |||
if (terminatesWithReturn()) { | |||
callback.append(fact.createReturn(extractedMethod.getReturnType())); | |||
} else { | |||
advice.append(fact.createBranchInstruction(Constants.GOTO, range.getEnd())); | |||
//InstructionHandle endNop = range.insert(fact.NOP, Range.InsideAfter); | |||
advice.append(fact.createBranchInstruction(Constants.GOTO, afterThingie.getStart())); | |||
} | |||
range.append(munger.getTestInstructions(this, advice.getStart(), callback.getStart(), advice.getStart())); | |||
range.append(advice); | |||
range.append(callback); | |||
range.append(callback); | |||
range.append(afterThingie); | |||
} | |||
// now the range contains everything we need. We now inline the advice method. | |||
LazyMethodGen adviceMethod = | |||
((BcelObjectType) munger.getConcreteAspect()) | |||
.getLazyClassGen() | |||
.getLazyMethodGen(munger.getSignature()); | |||
BcelClassWeaver.inlineMethod(adviceMethod, enclosingMethod, adviceMethodInvocation); | |||
@@ -1296,6 +1310,8 @@ public class BcelShadow extends Shadow { | |||
{ | |||
InstructionFactory fact = getFactory(); | |||
enclosingMethod.setCanInline(false); | |||
// MOVE OUT ALL THE INSTRUCTIONS IN MY SHADOW INTO ANOTHER METHOD! | |||
LazyMethodGen callbackMethod = | |||
extractMethod( |
@@ -156,7 +156,7 @@ public class BcelWorld extends World { | |||
} | |||
// ---- fluf | |||
public ResolvedTypeX resolveObjectType(TypeX ty) { | |||
protected ResolvedTypeX resolveObjectType(TypeX ty) { | |||
String name = ty.getName(); | |||
JavaClass jc = null; | |||
//UnwovenClassFile classFile = (UnwovenClassFile)sourceJavaClasses.get(name); |
@@ -295,6 +295,7 @@ public final class LazyClassGen { | |||
myGen.addAttribute(BcelAttributes.bcelAttribute( | |||
new AjAttribute.WeaverState(s), | |||
getConstantPoolGen())); | |||
myType.setWeaverState(s); | |||
} | |||
public InstructionFactory getFactory() { | |||
@@ -484,6 +485,7 @@ public final class LazyClassGen { | |||
if (gen.getName().equals(name) && gen.getSignature().equals(signature)) | |||
return gen; | |||
} | |||
throw new BCException("Class " + this.getName() + " does not have a method " | |||
+ name + " with signature " + signature); | |||
} |
@@ -51,6 +51,8 @@ public final class LazyMethodGen { | |||
private int maxLocals; | |||
private boolean canInline = true; | |||
/** | |||
* only used by {@link BcelClassWeaver} | |||
*/ | |||
@@ -434,7 +436,9 @@ public final class LazyMethodGen { | |||
String getRangeString(Range r, Map labelMap) { | |||
if (r instanceof ExceptionRange) { | |||
ExceptionRange er = (ExceptionRange) r; | |||
return er.toString() + " -> " + labelMap.get(er.getHandler()); | |||
return er.toString() + " -> " + labelMap.get(er.getHandler()); | |||
// | |||
// + " PRI " + er.getPriority(); | |||
} else { | |||
return r.toString(); | |||
} | |||
@@ -813,7 +817,11 @@ public final class LazyMethodGen { | |||
} | |||
} | |||
// exception ordering | |||
// exception ordering. | |||
// What we should be doing is dealing with priority inversions way earlier than we are | |||
// and counting on the tree structure. In which case, the below code is in fact right. | |||
// XXX THIS COMMENT BELOW IS CURRENTLY WRONG. | |||
// An exception A preceeds an exception B in the exception table iff: | |||
// * A and B were in the original method, and A preceeded B in the original exception table | |||
@@ -824,15 +832,15 @@ public final class LazyMethodGen { | |||
// but I don't trust the only implementation, TreeSet, to do the right thing. | |||
private static void insertHandler(ExceptionRange fresh, LinkedList l) { | |||
for (ListIterator iter = l.listIterator(); iter.hasNext();) { | |||
ExceptionRange r = (ExceptionRange) iter.next(); | |||
if (fresh.getPriority() >= r.getPriority()) { | |||
iter.previous(); | |||
iter.add(fresh); | |||
return; | |||
} | |||
} | |||
l.add(fresh); | |||
// for (ListIterator iter = l.listIterator(); iter.hasNext();) { | |||
// ExceptionRange r = (ExceptionRange) iter.next(); | |||
// if (fresh.getPriority() >= r.getPriority()) { | |||
// iter.previous(); | |||
// iter.add(fresh); | |||
// return; | |||
// } | |||
// } | |||
l.add(0, fresh); | |||
} | |||
@@ -1064,4 +1072,12 @@ public final class LazyMethodGen { | |||
accessFlags = Utility.makePublic(accessFlags); | |||
} | |||
public boolean getCanInline() { | |||
return canInline; | |||
} | |||
public void setCanInline(boolean canInline) { | |||
this.canInline = canInline; | |||
} | |||
} |
@@ -19,11 +19,11 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
method-execution(void FancyHelloWorld.main(java.lang.String[])) | |||
| catch java.lang.Throwable -> E6 | |||
| | field-get(java.io.PrintStream java.lang.System.out) | |||
| | | catch java.lang.Throwable -> E3 | |||
| | | catch java.lang.Throwable -> E5 | |||
| | | | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 9) | |||
| | | catch java.lang.Throwable -> E3 | |||
| | | catch java.lang.Throwable -> E5 | |||
| | | GOTO L0 | |||
| | | E3: ASTORE 5 | |||
| | | E5: ASTORE 5 | |||
| | | INVOKESTATIC Aspect.ajc_after_field_get ()V | |||
| | | ALOAD 5 | |||
| | | ATHROW | |||
@@ -32,8 +32,8 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| | | NOP | |||
| | field-get(java.io.PrintStream java.lang.System.out) | |||
| | ASTORE_1 | |||
| | finally -> E5 | |||
| | | catch java.lang.Exception -> E4 | |||
| | finally -> E4 | |||
| | | catch java.lang.Exception -> E3 | |||
| | | | ALOAD_1 // java.io.PrintStream out (line 11) | |||
| | | | LDC "bye" | |||
| | | | method-call(void java.io.PrintStream.println(java.lang.String)) | |||
@@ -50,8 +50,8 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| | | | | NOP | |||
| | | | method-call(void java.io.PrintStream.println(java.lang.String)) | |||
| | | | GOTO L3 | |||
| | | catch java.lang.Exception -> E4 | |||
| | | E4: ASTORE_2 (line 12) | |||
| | | catch java.lang.Exception -> E3 | |||
| | | E3: ASTORE_2 (line 12) | |||
| | | ALOAD_1 // java.io.PrintStream out (line 13) | |||
| | | ALOAD_2 // java.lang.Exception e | |||
| | | method-call(void java.io.PrintStream.println(java.lang.Object)) | |||
@@ -67,9 +67,9 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| | | | INVOKESTATIC Aspect.ajc_after_method_call ()V | |||
| | | | NOP | |||
| | | method-call(void java.io.PrintStream.println(java.lang.Object)) | |||
| | finally -> E5 | |||
| | finally -> E4 | |||
| | GOTO L3 | |||
| | E5: ASTORE 4 (line 14) | |||
| | E4: ASTORE 4 (line 14) | |||
| | JSR L4 | |||
| | ALOAD 4 | |||
| | ATHROW | |||
@@ -180,4 +180,5 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| ARETURN | |||
method-execution(java.lang.String FancyHelloWorld.getName()) | |||
end public static String getName() | |||
end public abstract class FancyHelloWorld |
@@ -17,19 +17,19 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
method-execution(void FancyHelloWorld.main(java.lang.String[])) | |||
| catch java.lang.Throwable -> E6 | |||
| | field-get(java.io.PrintStream java.lang.System.out) | |||
| | | catch java.lang.Throwable -> E3 | |||
| | | catch java.lang.Throwable -> E5 | |||
| | | | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 9) | |||
| | | catch java.lang.Throwable -> E3 | |||
| | | catch java.lang.Throwable -> E5 | |||
| | | GOTO L0 | |||
| | | E3: ASTORE 5 | |||
| | | E5: ASTORE 5 | |||
| | | INVOKESTATIC Aspect.ajc_afterThrowing_field_get ()V | |||
| | | ALOAD 5 | |||
| | | ATHROW | |||
| | | L0: NOP | |||
| | field-get(java.io.PrintStream java.lang.System.out) | |||
| | ASTORE_1 | |||
| | finally -> E5 | |||
| | | catch java.lang.Exception -> E4 | |||
| | finally -> E4 | |||
| | | catch java.lang.Exception -> E3 | |||
| | | | ALOAD_1 // java.io.PrintStream out (line 11) | |||
| | | | LDC "bye" | |||
| | | | method-call(void java.io.PrintStream.println(java.lang.String)) | |||
@@ -44,8 +44,8 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| | | | | L1: NOP | |||
| | | | method-call(void java.io.PrintStream.println(java.lang.String)) | |||
| | | | GOTO L3 | |||
| | | catch java.lang.Exception -> E4 | |||
| | | E4: ASTORE_2 (line 12) | |||
| | | catch java.lang.Exception -> E3 | |||
| | | E3: ASTORE_2 (line 12) | |||
| | | ALOAD_1 // java.io.PrintStream out (line 13) | |||
| | | ALOAD_2 // java.lang.Exception e | |||
| | | method-call(void java.io.PrintStream.println(java.lang.Object)) | |||
@@ -59,9 +59,9 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| | | | ATHROW | |||
| | | | L2: NOP | |||
| | | method-call(void java.io.PrintStream.println(java.lang.Object)) | |||
| | finally -> E5 | |||
| | finally -> E4 | |||
| | GOTO L3 | |||
| | E5: ASTORE 4 (line 14) | |||
| | E4: ASTORE 4 (line 14) | |||
| | JSR L4 | |||
| | ALOAD 4 | |||
| | ATHROW | |||
@@ -158,4 +158,5 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| ATHROW | |||
method-execution(java.lang.String FancyHelloWorld.getName()) | |||
end public static String getName() | |||
end public abstract class FancyHelloWorld |
@@ -10,11 +10,11 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
public static void main(String[]): | |||
method-execution(void FancyHelloWorld.main(java.lang.String[])) | |||
| field-get(java.io.PrintStream java.lang.System.out) | |||
| | catch java.lang.Throwable -> E0 | |||
| | catch java.lang.Throwable -> E2 | |||
| | | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 9) | |||
| | catch java.lang.Throwable -> E0 | |||
| | catch java.lang.Throwable -> E2 | |||
| | GOTO L0 | |||
| | E0: ASTORE 5 | |||
| | E2: ASTORE 5 | |||
| | ALOAD 5 | |||
| | INVOKESTATIC Aspect.ajc_afterThrowing_field_get (Ljava/lang/Throwable;)V | |||
| | ALOAD 5 | |||
@@ -22,24 +22,24 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| | L0: NOP | |||
| field-get(java.io.PrintStream java.lang.System.out) | |||
| ASTORE_1 | |||
| finally -> E2 | |||
| | catch java.lang.Exception -> E1 | |||
| finally -> E1 | |||
| | catch java.lang.Exception -> E0 | |||
| | | ALOAD_1 // java.io.PrintStream out (line 11) | |||
| | | LDC "bye" | |||
| | | method-call(void java.io.PrintStream.println(java.lang.String)) | |||
| | | | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V | |||
| | | method-call(void java.io.PrintStream.println(java.lang.String)) | |||
| | | GOTO L1 | |||
| | catch java.lang.Exception -> E1 | |||
| | E1: ASTORE_2 (line 12) | |||
| | catch java.lang.Exception -> E0 | |||
| | E0: ASTORE_2 (line 12) | |||
| | ALOAD_1 // java.io.PrintStream out (line 13) | |||
| | ALOAD_2 // java.lang.Exception e | |||
| | method-call(void java.io.PrintStream.println(java.lang.Object)) | |||
| | | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/Object;)V | |||
| | method-call(void java.io.PrintStream.println(java.lang.Object)) | |||
| finally -> E2 | |||
| finally -> E1 | |||
| GOTO L1 | |||
| E2: ASTORE 4 (line 14) | |||
| E1: ASTORE 4 (line 14) | |||
| JSR L2 | |||
| ALOAD 4 | |||
| ATHROW | |||
@@ -83,4 +83,5 @@ public abstract class FancyHelloWorld extends java.lang.Object: | |||
| ARETURN | |||
method-execution(java.lang.String FancyHelloWorld.getName()) | |||
end public static String getName() | |||
end public abstract class FancyHelloWorld |
@@ -66,33 +66,46 @@ public class DynamicHelloWorld extends java.lang.Object implements java.io.Seria | |||
| ALOAD_0 | |||
| INVOKEVIRTUAL Trace.ajc$before$Trace$51 (Ljava/lang/Object;)V | |||
| INVOKESTATIC MyTrace.aspectOf ()LMyTrace; | |||
| BIPUSH 3 | |||
| ANEWARRAY java.lang.Object | |||
| ASTORE 6 | |||
| ALOAD 6 | |||
| BIPUSH 0 | |||
| ACONST_NULL | |||
| ASTORE 13 | |||
| ASTORE 12 | |||
| LDC "Hi" (line 9) | |||
| ASTORE 14 | |||
| GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 10) | |||
| NEW java.lang.StringBuffer | |||
| DUP | |||
| LDC "start around: " | |||
| INVOKESPECIAL java.lang.StringBuffer.<init> (Ljava/lang/String;)V | |||
| ALOAD 14 | |||
| INVOKEVIRTUAL java.lang.StringBuffer.append (Ljava/lang/Object;)Ljava/lang/StringBuffer; | |||
| INVOKEVIRTUAL java.lang.StringBuffer.toString ()Ljava/lang/String; | |||
| INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V | |||
| ALOAD 13 (line 11) | |||
| ASTORE 18 | |||
| ALOAD_0 | |||
| AASTORE | |||
| ALOAD 6 | |||
| BIPUSH 1 | |||
| ALOAD_3 | |||
| AASTORE | |||
| ALOAD 6 | |||
| BIPUSH 2 | |||
| ALOAD 4 | |||
| AASTORE | |||
| NEW DynamicHelloWorld$AjcClosure3 | |||
| INVOKESTATIC DynamicHelloWorld.doit_aroundBody1 (LDynamicHelloWorld;Ljava/lang/String;Ljava/util/List;)Ljava/lang/String; | |||
| ASTORE 16 | |||
| GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 12) | |||
| NEW java.lang.StringBuffer | |||
| DUP | |||
| ALOAD 6 | |||
| INVOKESPECIAL DynamicHelloWorld$AjcClosure3.<init> ([Ljava/lang/Object;)V | |||
| INVOKEVIRTUAL Trace.ajc$around$Trace$cc (Lorg/aspectj/runtime/internal/AroundClosure;)Ljava/lang/Object; | |||
| CHECKCAST java.lang.String | |||
| LDC "exiting around with: " | |||
| INVOKESPECIAL java.lang.StringBuffer.<init> (Ljava/lang/String;)V | |||
| ALOAD 16 | |||
| INVOKEVIRTUAL java.lang.StringBuffer.append (Ljava/lang/Object;)Ljava/lang/StringBuffer; | |||
| INVOKEVIRTUAL java.lang.StringBuffer.toString ()Ljava/lang/String; | |||
| INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V | |||
| ALOAD 16 (line 13) | |||
| GOTO L0 | |||
| L0: DUP | |||
| ASTORE 7 | |||
| L0: NOP | |||
| CHECKCAST java.lang.String | |||
| GOTO L1 | |||
| L1: DUP | |||
| ASTORE 19 | |||
| INVOKESTATIC MyTrace.aspectOf ()LMyTrace; | |||
| ALOAD_0 | |||
| ALOAD 7 | |||
| ALOAD 19 | |||
| INVOKEVIRTUAL MyTrace.ajc$afterReturning$MyTrace$6e (Ljava/lang/Object;Ljava/lang/Object;)V | |||
| ARETURN | |||
method-execution(java.lang.String DynamicHelloWorld.doit(java.lang.String, java.util.List)) | |||
@@ -112,88 +125,45 @@ public class DynamicHelloWorld extends java.lang.Object implements java.io.Seria | |||
ARETURN | |||
end static final String doit_aroundBody0(DynamicHelloWorld, String, java.util.List) | |||
static final String doit_aroundBody2(DynamicHelloWorld, String, java.util.List): | |||
static final String doit_aroundBody1(DynamicHelloWorld, String, java.util.List): | |||
INVOKESTATIC MyTrace.aspectOf ()LMyTrace; | |||
ALOAD_0 | |||
BIPUSH 3 | |||
ANEWARRAY java.lang.Object | |||
ACONST_NULL | |||
ASTORE_3 | |||
ALOAD_3 | |||
BIPUSH 0 | |||
ALOAD_0 | |||
AASTORE | |||
ALOAD_3 | |||
BIPUSH 1 | |||
ALOAD_1 | |||
AASTORE | |||
ALOAD_3 | |||
BIPUSH 2 | |||
ALOAD_2 | |||
AASTORE | |||
NEW DynamicHelloWorld$AjcClosure1 | |||
ASTORE 5 | |||
ASTORE 7 | |||
GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 17) | |||
NEW java.lang.StringBuffer | |||
DUP | |||
LDC "start around(2): " | |||
INVOKESPECIAL java.lang.StringBuffer.<init> (Ljava/lang/String;)V | |||
ALOAD 5 | |||
INVOKEVIRTUAL java.lang.StringBuffer.append (Ljava/lang/Object;)Ljava/lang/StringBuffer; | |||
INVOKEVIRTUAL java.lang.StringBuffer.toString ()Ljava/lang/String; | |||
INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V | |||
ALOAD 5 (line 18) | |||
ALOAD_3 | |||
INVOKESPECIAL DynamicHelloWorld$AjcClosure1.<init> ([Ljava/lang/Object;)V | |||
INVOKEVIRTUAL Trace.ajc$around$Trace$1bc (Ljava/lang/Object;Lorg/aspectj/runtime/internal/AroundClosure;)Ljava/lang/Object; | |||
CHECKCAST java.lang.String | |||
ARETURN | |||
end static final String doit_aroundBody2(DynamicHelloWorld, String, java.util.List) | |||
end public class DynamicHelloWorld | |||
public class DynamicHelloWorld$AjcClosure1 extends org.aspectj.runtime.internal.AroundClosure: | |||
public void <init>(Object[]): | |||
ALOAD_0 | |||
ALOAD_1 | |||
INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V | |||
RETURN | |||
end public void <init>(Object[]) | |||
public Object run(Object[]): | |||
ALOAD_0 | |||
GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; | |||
ASTORE_2 | |||
ALOAD_1 | |||
BIPUSH 0 | |||
AALOAD | |||
ASTORE 9 | |||
ASTORE 11 | |||
ALOAD 11 | |||
CHECKCAST DynamicHelloWorld | |||
ALOAD_2 | |||
BIPUSH 1 | |||
AALOAD | |||
CHECKCAST java.lang.String | |||
ALOAD_2 | |||
BIPUSH 2 | |||
AALOAD | |||
CHECKCAST java.util.List | |||
INVOKESTATIC DynamicHelloWorld.doit_aroundBody0 (LDynamicHelloWorld;Ljava/lang/String;Ljava/util/List;)Ljava/lang/String; | |||
ARETURN | |||
end public Object run(Object[]) | |||
end public class DynamicHelloWorld$AjcClosure1 | |||
public class DynamicHelloWorld$AjcClosure3 extends org.aspectj.runtime.internal.AroundClosure: | |||
public void <init>(Object[]): | |||
ALOAD_0 | |||
ALOAD_1 | |||
INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V | |||
RETURN | |||
end public void <init>(Object[]) | |||
public Object run(Object[]): | |||
ALOAD_0 | |||
GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object; | |||
ASTORE_2 | |||
ALOAD_2 | |||
BIPUSH 0 | |||
AALOAD | |||
CHECKCAST DynamicHelloWorld | |||
ALOAD_2 | |||
BIPUSH 1 | |||
AALOAD | |||
INVOKESTATIC DynamicHelloWorld.doit_aroundBody0 (LDynamicHelloWorld;Ljava/lang/String;Ljava/util/List;)Ljava/lang/String; | |||
ASTORE 13 | |||
GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 19) | |||
NEW java.lang.StringBuffer | |||
DUP | |||
LDC "exiting around with(2): " | |||
INVOKESPECIAL java.lang.StringBuffer.<init> (Ljava/lang/String;)V | |||
ALOAD 13 | |||
INVOKEVIRTUAL java.lang.StringBuffer.append (Ljava/lang/Object;)Ljava/lang/StringBuffer; | |||
INVOKEVIRTUAL java.lang.StringBuffer.toString ()Ljava/lang/String; | |||
INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V | |||
ALOAD 13 (line 20) | |||
GOTO L0 | |||
L0: NOP | |||
CHECKCAST java.lang.String | |||
ALOAD_2 | |||
BIPUSH 2 | |||
AALOAD | |||
CHECKCAST java.util.List | |||
INVOKESTATIC DynamicHelloWorld.doit_aroundBody2 (LDynamicHelloWorld;Ljava/lang/String;Ljava/util/List;)Ljava/lang/String; | |||
ARETURN | |||
end public Object run(Object[]) | |||
end public class DynamicHelloWorld$AjcClosure3 | |||
end static final String doit_aroundBody1(DynamicHelloWorld, String, java.util.List) | |||
end public class DynamicHelloWorld |