Explorar el Código

finished implementation of around inlining

tags/V_1_1_b5
jhugunin hace 21 años
padre
commit
28f09b17d4
Se han modificado 24 ficheros con 645 adiciones y 159 borrados
  1. 2
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
  2. 114
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java
  3. 42
    8
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java
  4. 57
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/MakeDeclsPublicVisitor.java
  5. 5
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java
  6. 224
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ProceedVisitor.java
  7. 9
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
  8. 2
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
  9. 6
    6
      org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java
  10. 1
    1
      weaver/src/org/aspectj/weaver/Advice.java
  11. 4
    0
      weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java
  12. 2
    0
      weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
  13. 3
    2
      weaver/src/org/aspectj/weaver/ResolvedTypeX.java
  14. 10
    0
      weaver/src/org/aspectj/weaver/World.java
  15. 16
    2
      weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
  16. 1
    0
      weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
  17. 22
    6
      weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
  18. 1
    1
      weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
  19. 2
    0
      weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
  20. 27
    11
      weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
  21. 10
    9
      weaver/testdata/AfterFancyHelloWorld.txt
  22. 10
    9
      weaver/testdata/AfterThrowingFancyHelloWorld.txt
  23. 10
    9
      weaver/testdata/AfterThrowingParamFancyHelloWorld.txt
  24. 65
    95
      weaver/testdata/TraceJarHello.txt

+ 2
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java Ver fichero

@@ -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());

+ 114
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java Ver fichero

@@ -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;
}
}
}

+ 42
- 8
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java Ver fichero

@@ -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);
}
}
}



+ 57
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/MakeDeclsPublicVisitor.java Ver fichero

@@ -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);
}

}

+ 5
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java Ver fichero

@@ -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);

+ 224
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ProceedVisitor.java Ver fichero

@@ -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;
}


}

+ 9
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java Ver fichero

@@ -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;
}

}

+ 2
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java Ver fichero

@@ -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;

+ 6
- 6
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java Ver fichero

@@ -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/";

+ 1
- 1
weaver/src/org/aspectj/weaver/Advice.java Ver fichero

@@ -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;

+ 4
- 0
weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java Ver fichero

@@ -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;
}

+ 2
- 0
weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java Ver fichero

@@ -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);

+ 3
- 2
weaver/src/org/aspectj/weaver/ResolvedTypeX.java Ver fichero

@@ -33,7 +33,6 @@ public abstract class ResolvedTypeX extends TypeX {

// ---- things that don't require a world


/** returns Iterator&lt;ResolvedTypeX&gt;
*/
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;
}

+ 10
- 0
weaver/src/org/aspectj/weaver/World.java Ver fichero

@@ -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;
}

}

+ 16
- 2
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java Ver fichero

@@ -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()) {

+ 1
- 0
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java Ver fichero

@@ -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;
}

+ 22
- 6
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java Ver fichero

@@ -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(

+ 1
- 1
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java Ver fichero

@@ -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);

+ 2
- 0
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java Ver fichero

@@ -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);
}

+ 27
- 11
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java Ver fichero

@@ -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;
}

}

+ 10
- 9
weaver/testdata/AfterFancyHelloWorld.txt Ver fichero

@@ -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

+ 10
- 9
weaver/testdata/AfterThrowingFancyHelloWorld.txt Ver fichero

@@ -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
- 9
weaver/testdata/AfterThrowingParamFancyHelloWorld.txt Ver fichero

@@ -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

+ 65
- 95
weaver/testdata/TraceJarHello.txt Ver fichero

@@ -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

Cargando…
Cancelar
Guardar