diff options
34 files changed, 1104 insertions, 34 deletions
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java index c5db1904a..4e1e6c8a8 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java @@ -761,6 +761,7 @@ public class InstructionFactory implements InstructionConstants { iList.append(new InstructionCP(Instruction.LDC_W, classIndex)); } } else { + className = className.replace('/', '.'); iList.append(InstructionFactory.PUSH(cp, className)); iList.append(this.createInvoke("java.lang.Class", "forName", ObjectType.CLASS, Type.STRINGARRAY1, Constants.INVOKESTATIC)); diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java index e1dc47348..9ce007b4f 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java @@ -89,9 +89,9 @@ public abstract class Type { public static final BasicType CHAR = new BasicType(Constants.T_CHAR); public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); public static final ObjectType STRING = new ObjectType("java.lang.String"); - public static final ObjectType OBJECT_ARRAY = new ObjectType("java.lang.Object[]"); - public static final ObjectType STRING_ARRAY = new ObjectType("java.lang.String[]"); - public static final ObjectType CLASS_ARRAY = new ObjectType("java.lang.Class[]"); + public static final ArrayType OBJECT_ARRAY = new ArrayType("java.lang.Object",1); + public static final ArrayType STRING_ARRAY = new ArrayType("java.lang.String",1); + public static final ArrayType CLASS_ARRAY = new ArrayType("java.lang.Class",1); public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); public static final ObjectType STRINGBUILDER = new ObjectType("java.lang.StringBuilder"); public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); @@ -130,6 +130,7 @@ public abstract class Type { commonTypes.put(CLASS.getSignature(), CLASS); commonTypes.put(OBJECT.getSignature(), OBJECT); commonTypes.put(STRING_ARRAY.getSignature(), STRING_ARRAY); + commonTypes.put(CLASS_ARRAY.getSignature(), CLASS_ARRAY); commonTypes.put(OBJECT_ARRAY.getSignature(), OBJECT_ARRAY); commonTypes.put(INTEGER.getSignature(), INTEGER); commonTypes.put(EXCEPTION.getSignature(), EXCEPTION); diff --git a/build/products/tools/dist/lib/aspectjrt.jar b/build/products/tools/dist/lib/aspectjrt.jar Binary files differindex e69de29bb..935830ebc 100644 --- a/build/products/tools/dist/lib/aspectjrt.jar +++ b/build/products/tools/dist/lib/aspectjrt.jar diff --git a/build/updateAspectjrt.sh b/build/updateAspectjrt.sh new file mode 100755 index 000000000..03fcd7f2f --- /dev/null +++ b/build/updateAspectjrt.sh @@ -0,0 +1,3 @@ +cp ../aj-build/dist/tools/lib/aspectjrt.jar ../lib/test/aspectjrt.jar +cp ../aj-build/dist/tools/lib/aspectjrt.jar ../lib/aspectj/lib/aspectjrt.jar +cp ../aj-build/dist/tools/lib/aspectjrt.jar ../build/products/tools/dist/lib/aspectjrt.jar diff --git a/lib/aspectj/lib/aspectjrt.jar b/lib/aspectj/lib/aspectjrt.jar Binary files differindex ef06aa7fd..935830ebc 100644 --- a/lib/aspectj/lib/aspectjrt.jar +++ b/lib/aspectj/lib/aspectjrt.jar diff --git a/lib/bcel/bcel-src.zip b/lib/bcel/bcel-src.zip Binary files differindex 1cbe73979..b98e0889e 100644 --- a/lib/bcel/bcel-src.zip +++ b/lib/bcel/bcel-src.zip diff --git a/lib/bcel/bcel-verifier.jar b/lib/bcel/bcel-verifier.jar Binary files differindex b55ed6429..cee235ad9 100644 --- a/lib/bcel/bcel-verifier.jar +++ b/lib/bcel/bcel-verifier.jar diff --git a/lib/bcel/bcel.jar b/lib/bcel/bcel.jar Binary files differindex 2306787c5..793bf0d0d 100644 --- a/lib/bcel/bcel.jar +++ b/lib/bcel/bcel.jar diff --git a/lib/test/aspectjrt.jar b/lib/test/aspectjrt.jar Binary files differindex f0c7d5f7c..935830ebc 100644 --- a/lib/test/aspectjrt.jar +++ b/lib/test/aspectjrt.jar diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java index ada5639ef..032719165 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java @@ -807,8 +807,10 @@ public class BuildArgParser extends Main { buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_12); } else if (arg.endsWith(":1.5")) { buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_15); + } else if (arg.endsWith(":1.9")) { + buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_19); } else { - showError("-Xajruntimetarget:<level> only supports a target level of 1.2 or 1.5"); + showError("-Xajruntimetarget:<level> supports a target level of 1.2, 1.5, 1.9"); } } else if (arg.equals("-timers")) { buildConfig.setTiming(true); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java index b92a4b439..4c7873df0 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.util.StringTokenizer; public class ConfigParser { Location location; @@ -44,6 +45,13 @@ public class ConfigParser { for (int i = 0; i < argsArray.length; i++) { args.add(new Arg(argsArray[i], location)); } + String aspectjOptions = System.getProperty("ASPECTJ_OPTS"); + if (aspectjOptions != null) { + StringTokenizer st = new StringTokenizer(aspectjOptions); + while (st.hasMoreElements()) { + args.add(new Arg(st.nextToken(),location)); + } + } parseArgs(args); } @@ -138,12 +146,14 @@ public class ConfigParser { if (sourceFile.getName().charAt(0) == '*') { if (sourceFile.getName().equals("*.java")) { addFiles(sourceFile.getParentFile(), new FileFilter() { + @Override public boolean accept(File f) { return f != null && f.getName().endsWith(".java"); } }); } else if (sourceFile.getName().equals("*.aj")) { addFiles(sourceFile.getParentFile(), new FileFilter() { + @Override public boolean accept(File f) { return f != null && f.getName().endsWith(".aj"); } @@ -287,6 +297,7 @@ public class ConfigParser { private Location location; private String value; + @Override public String toString() { return "Arg[location="+location+" value="+value+"]"; } @@ -320,6 +331,7 @@ public class ConfigParser { public abstract int getLine(); + @Override public abstract String toString(); } @@ -332,36 +344,44 @@ public class ConfigParser { this.file = file; } + @Override public File getFile() { return file; } + @Override public File getDirectory() { return file.getParentFile(); } + @Override public int getLine() { return line; } + @Override public String toString() { return file.getPath() + ":" + line; } } static class CommandLineLocation extends Location { + @Override public File getFile() { return new File(System.getProperty("user.dir")); } + @Override public File getDirectory() { return new File(System.getProperty("user.dir")); } + @Override public int getLine() { return -1; } + @Override public String toString() { return "command-line"; } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/Constants.java b/org.aspectj.matcher/src/org/aspectj/weaver/Constants.java index 4b99a32ab..bdbde3853 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/Constants.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/Constants.java @@ -22,6 +22,7 @@ public interface Constants { public final static String RUNTIME_LEVEL_12 = "1.2"; public final static String RUNTIME_LEVEL_15 = "1.5"; + public final static String RUNTIME_LEVEL_19 = "1.9"; // Default for 1.5.0 public final static String RUNTIME_LEVEL_DEFAULT = RUNTIME_LEVEL_15; diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/RuntimeVersion.java b/org.aspectj.matcher/src/org/aspectj/weaver/RuntimeVersion.java new file mode 100644 index 000000000..0cf90a9a2 --- /dev/null +++ b/org.aspectj.matcher/src/org/aspectj/weaver/RuntimeVersion.java @@ -0,0 +1,47 @@ +/* ******************************************************************* + * Copyright (c) 2018 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * ******************************************************************/ +package org.aspectj.weaver; + +/** + * Captures important runtime versions. Typically new versions are added here if something + * changes in the runtime and the code generation may be able to do something different + * (more optimal) for a later runtime. + * + * @author Andy Clement + */ +public enum RuntimeVersion { + + V1_2("1.2"), V1_5("1.5"), V1_6_10("1.6.10"), V1_9("1.9"); + + private String[] aliases = null; + + RuntimeVersion(String... aliases) { + this.aliases = aliases; + } + + public static RuntimeVersion getVersionFor(String version) { + for (RuntimeVersion candidateVersion: values()) { + if (candidateVersion.name().equals(version)) { + return candidateVersion; + } + if (candidateVersion.aliases != null) { + for (String alias: candidateVersion.aliases) { + if (alias.equals(version)) { + return candidateVersion; + } + } + } + } + return null; + } + + public boolean isThisVersionOrLater(RuntimeVersion version) { + return this.compareTo(version) >= 0; + } +} diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/World.java b/org.aspectj.matcher/src/org/aspectj/weaver/World.java index 19d61f5be..644f232ac 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/World.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/World.java @@ -110,8 +110,9 @@ public abstract class World implements Dump.INode { private boolean incrementalCompileCouldFollow = false; /** The level of the aspectjrt.jar the code we generate needs to run on */ - private String targetAspectjRuntimeLevel = Constants.RUNTIME_LEVEL_DEFAULT; - + public static final RuntimeVersion RUNTIME_LEVEL_DEFAULT = RuntimeVersion.V1_5; + private RuntimeVersion targetAspectjRuntimeLevel = RUNTIME_LEVEL_DEFAULT; + /** Flags for the new joinpoints that are 'optional': -Xjoinpoints:arrayconstruction -Xjoinpoints:synchronization */ private boolean optionalJoinpoint_ArrayConstruction = false; private boolean optionalJoinpoint_Synchronization = false; @@ -202,6 +203,7 @@ public abstract class World implements Dump.INode { /** * Dump processing when a fatal error occurs */ + @Override public void accept(Dump.IVisitor visitor) { // visitor.visitObject("Extra configuration:"); // visitor.visitList(extraConfiguration.); @@ -982,7 +984,7 @@ public abstract class World implements Dump.INode { } public void setTargetAspectjRuntimeLevel(String s) { - targetAspectjRuntimeLevel = s; + targetAspectjRuntimeLevel = RuntimeVersion.getVersionFor(s); } public void setOptionalJoinpoints(String jps) { @@ -1005,20 +1007,18 @@ public abstract class World implements Dump.INode { return optionalJoinpoint_Synchronization; } - public String getTargetAspectjRuntimeLevel() { + public RuntimeVersion getTargetAspectjRuntimeLevel() { return targetAspectjRuntimeLevel; } - // OPTIMIZE are users falling foul of not supplying -1.5 and so targetting - // the old runtime? + // OPTIMIZE are users falling foul of not supplying -1.5 and so targetting the old runtime? public boolean isTargettingAspectJRuntime12() { boolean b = false; // pr116679 if (!isInJava5Mode()) { b = true; } else { - b = getTargetAspectjRuntimeLevel().equals(org.aspectj.weaver.Constants.RUNTIME_LEVEL_12); + b = (getTargetAspectjRuntimeLevel() == RuntimeVersion.V1_2); } - // System.err.println("Asked if targetting runtime 1.2 , returning: "+b); return b; } diff --git a/runtime/src/org/aspectj/runtime/reflect/Factory.java b/runtime/src/org/aspectj/runtime/reflect/Factory.java index 06e073873..759a1367b 100644 --- a/runtime/src/org/aspectj/runtime/reflect/Factory.java +++ b/runtime/src/org/aspectj/runtime/reflect/Factory.java @@ -1,6 +1,6 @@ /* ******************************************************************* * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). + * 2002-2018 Palo Alto Research Center, Incorporated (PARC), Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 @@ -8,9 +8,10 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Xerox/PARC initial implementation + * Xerox/PARC initial implementation * Alex Vasseur new factory methods for variants of JP - * Abraham Nevado new factory methods for collapsed SJPs + * Abraham Nevado new factory methods for collapsed SJPs + * Andy Clement new factory methods that rely on LDC <class> * ******************************************************************/ package org.aspectj.runtime.reflect; @@ -38,6 +39,9 @@ public final class Factory { ClassLoader lookupClassLoader; String filename; int count; + + private static final Class[] NO_TYPES = new Class[0]; + private static final String[] NO_STRINGS = new String[0]; static Hashtable prims = new Hashtable(); static { @@ -55,7 +59,7 @@ public final class Factory { static Class makeClass(String s, ClassLoader loader) { if (s.equals("*")) return null; - Class ret = (Class) prims.get(s); + Class ret = (Class)prims.get(s); if (ret != null) return ret; try { @@ -113,6 +117,105 @@ public final class Factory { Signature sig = this.makeMethodSig(modifiers, methodName, declaringType, paramTypes, paramNames, "", returnType); return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(l, -1)); } + + // These are direct routes to creating thisJoinPoint and thisEnclosingJoinPoint objects + // added in 1.9.1 + + public JoinPoint.StaticPart makeMethodSJP(String kind, int modifiers, String methodName, Class declaringType, Class[] paramTypes, String[] paramNames, Class[] exceptionTypes, Class returnType, int line) { + Signature sig = this.makeMethodSig(modifiers, methodName, declaringType, paramTypes==null?NO_TYPES:paramTypes, + paramNames==null?NO_STRINGS:paramNames, exceptionTypes==null?NO_TYPES:exceptionTypes, returnType == null?Void.TYPE:returnType); + return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.EnclosingStaticPart makeMethodESJP(String kind, int modifiers, String methodName, Class declaringType, Class[] paramTypes, String[] paramNames, Class[] exceptionTypes, Class returnType, int line) { + Signature sig = this.makeMethodSig(modifiers, methodName, declaringType, paramTypes==null?NO_TYPES:paramTypes, + paramNames==null?NO_STRINGS:paramNames, exceptionTypes==null?NO_TYPES:exceptionTypes, returnType == null?Void.TYPE:returnType); + return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.StaticPart makeConstructorSJP(String kind, int modifiers, Class declaringType, Class[] parameterTypes, String[] parameterNames, Class[] exceptionTypes, int line) { + ConstructorSignatureImpl sig = new ConstructorSignatureImpl(modifiers, declaringType, parameterTypes==null?NO_TYPES:parameterTypes, parameterNames==null?NO_STRINGS:parameterNames, + exceptionTypes==null?NO_TYPES:exceptionTypes); + return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.EnclosingStaticPart makeConstructorESJP(String kind, int modifiers, Class declaringType, Class[] parameterTypes, String[] parameterNames, Class[] exceptionTypes, int line) { + ConstructorSignatureImpl sig = new ConstructorSignatureImpl(modifiers, declaringType, parameterTypes==null?NO_TYPES:parameterTypes, parameterNames==null?NO_STRINGS:parameterNames, + exceptionTypes==null?NO_TYPES:exceptionTypes); + return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.StaticPart makeCatchClauseSJP(String kind, Class declaringType, Class parameterType, String parameterName, int line) { + CatchClauseSignatureImpl sig = new CatchClauseSignatureImpl(declaringType, parameterType, parameterName==null?"":parameterName); + return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.EnclosingStaticPart makeCatchClauseESJP(String kind, Class declaringType, Class parameterType, String parameterName, int line) { + CatchClauseSignatureImpl sig = new CatchClauseSignatureImpl(declaringType, parameterType, parameterName==null?"":parameterName); + return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.StaticPart makeFieldSJP(String kind, int modifiers, String name, Class declaringType, Class fieldType, int line) { + FieldSignatureImpl sig = new FieldSignatureImpl(modifiers, name, declaringType, fieldType); + return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.EnclosingStaticPart makeFieldESJP(String kind, int modifiers, String name, Class declaringType, Class fieldType, int line) { + FieldSignatureImpl sig = new FieldSignatureImpl(modifiers, name, declaringType, fieldType); + return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.StaticPart makeInitializerSJP(String kind, int modifiers, Class declaringType, int line) { + InitializerSignatureImpl sig = new InitializerSignatureImpl(modifiers, declaringType); + return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.EnclosingStaticPart makeInitializerESJP(String kind, int modifiers, Class declaringType, int line) { + InitializerSignatureImpl sig = new InitializerSignatureImpl(modifiers, declaringType); + return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.StaticPart makeLockSJP(String kind, Class declaringType, int line) { + LockSignatureImpl sig = new LockSignatureImpl(declaringType); + return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.EnclosingStaticPart makeLockESJP(String kind, Class declaringType, int line) { + LockSignatureImpl sig = new LockSignatureImpl(declaringType); + return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.StaticPart makeUnlockSJP(String kind, Class declaringType, int line) { + UnlockSignatureImpl sig = new UnlockSignatureImpl(declaringType); + return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.EnclosingStaticPart makeUnlockESJP(String kind, Class declaringType, int line) { + UnlockSignatureImpl sig = new UnlockSignatureImpl(declaringType); + return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.StaticPart makeAdviceSJP(String kind, int modifiers, String name, Class declaringType, Class[] parameterTypes, + String[] parameterNames, Class[] exceptionTypes, Class returnType, int line) { + AdviceSignatureImpl sig = new AdviceSignatureImpl(modifiers, name, declaringType, + parameterTypes==null?NO_TYPES:parameterTypes, + parameterNames==null?NO_STRINGS:parameterNames, + exceptionTypes==null?NO_TYPES:exceptionTypes, + returnType==null?Void.TYPE:returnType); + return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + public JoinPoint.EnclosingStaticPart makeAdviceESJP(String kind, int modifiers, String name, Class declaringType, Class[] parameterTypes, + String[] parameterNames, Class[] exceptionTypes, Class returnType, int line) { + AdviceSignatureImpl sig = new AdviceSignatureImpl(modifiers, name, declaringType, + parameterTypes==null?NO_TYPES:parameterTypes, + parameterNames==null?NO_STRINGS:parameterNames, + exceptionTypes==null?NO_TYPES:exceptionTypes, + returnType==null?Void.TYPE:returnType); + return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1)); + } + + // --- public JoinPoint.StaticPart makeSJP(String kind, Signature sig, SourceLocation loc) { return new JoinPointImpl.StaticPartImpl(count++, kind, sig, loc); @@ -181,12 +284,16 @@ public final class Factory { ret.setLookupClassLoader(lookupClassLoader); return ret; } - + public MethodSignature makeMethodSig(String modifiers, String methodName, String declaringType, String paramTypes, String paramNames, String exceptionTypes, String returnType) { - int modifiersAsInt = Integer.parseInt(modifiers, 16); - Class declaringTypeClass = makeClass(declaringType, lookupClassLoader); + return makeMethodSig(modifiers, methodName, declaringTypeClass, paramTypes, paramNames, exceptionTypes, returnType); + } + + public MethodSignature makeMethodSig(String modifiers, String methodName, Class declaringTypeClass, String paramTypes, + String paramNames, String exceptionTypes, String returnType) { + int modifiersAsInt = Integer.parseInt(modifiers, 16); StringTokenizer st = new StringTokenizer(paramTypes, ":"); int numParams = st.countTokens(); @@ -216,8 +323,8 @@ public final class Factory { public MethodSignature makeMethodSig(int modifiers, String name, Class declaringType, Class[] parameterTypes, String[] parameterNames, Class[] exceptionTypes, Class returnType) { - MethodSignatureImpl ret = new MethodSignatureImpl(modifiers, name, declaringType, parameterTypes, parameterNames, - exceptionTypes, returnType); + MethodSignatureImpl ret = new MethodSignatureImpl(modifiers, name, declaringType, parameterTypes==null?NO_TYPES:parameterTypes, parameterNames, + exceptionTypes == null?NO_TYPES:exceptionTypes, returnType); ret.setLookupClassLoader(lookupClassLoader); return ret; } diff --git a/tests/features190/efficientTJP/Advice.java b/tests/features190/efficientTJP/Advice.java new file mode 100644 index 000000000..a85a445c2 --- /dev/null +++ b/tests/features190/efficientTJP/Advice.java @@ -0,0 +1,19 @@ +public class Advice { + public static void main(String []argv) { + } +} + +aspect X { + before(): execution(* main(..)) {} +} + +aspect Y { + before(): adviceexecution() && within(X) { + System.out.println("tjp:"+thisJoinPointStaticPart.getSignature()); + } + + before(): adviceexecution() && within(X) { + System.out.println("tejp:"+thisEnclosingJoinPointStaticPart.getSignature()); + } + +} diff --git a/tests/features190/efficientTJP/Clinit.java b/tests/features190/efficientTJP/Clinit.java new file mode 100644 index 000000000..e8acea835 --- /dev/null +++ b/tests/features190/efficientTJP/Clinit.java @@ -0,0 +1,16 @@ +public class Clinit { + public static void main(String []argv) { + new Inner(); + } + + static class Inner {} +} + +aspect X { + before(): staticinitialization(Clinit.Inner) { + System.out.println(thisJoinPointStaticPart.getSignature()); + } + before(): staticinitialization(Clinit) { + System.out.println(thisJoinPointStaticPart.getSignature()); + } +} diff --git a/tests/features190/efficientTJP/ClinitE.java b/tests/features190/efficientTJP/ClinitE.java new file mode 100644 index 000000000..a007a2014 --- /dev/null +++ b/tests/features190/efficientTJP/ClinitE.java @@ -0,0 +1,16 @@ +public class ClinitE { + public static void main(String []argv) { + new Inner(); + } + + static class Inner {} +} + +aspect X { + before(): staticinitialization(ClinitE.Inner) { + System.out.println(thisEnclosingJoinPointStaticPart.getSignature()); + } + before(): staticinitialization(ClinitE) { + System.out.println(thisEnclosingJoinPointStaticPart.getSignature()); + } +} diff --git a/tests/features190/efficientTJP/Fields.java b/tests/features190/efficientTJP/Fields.java new file mode 100644 index 000000000..ad1246568 --- /dev/null +++ b/tests/features190/efficientTJP/Fields.java @@ -0,0 +1,46 @@ +public class Fields { + int a = 1; + String s = "hello"; + double d = 1.0d; + boolean b = true; + + short ps = (short)1; + float fs = 1.0f; + long ls = 1L; + byte bs = (byte)3; + char cs = 'a'; + + + Inner obj = new Inner(); + static int as = 1; + static String ss = "hello"; + static double ds = 1.0d; + static Inner objs = new Inner(); + + public static void main(String []argv) { + Fields f = new Fields(); + int a2 = f.a; + String s2 = f.s; + double d2 = f.d; + Inner obj2 = f.obj; + + short ps2 = f.ps; + float fs2 = f.fs; + long ls2 = f.ls; + byte bs2 = f.bs; + char cs2 = f.cs; + + int a3 = as; + String s3 = ss; + double d3 = ds; + Inner obj3 = objs; + } + + static class Inner {} +} + +aspect X { + before(): within(Fields) && get(* *) { + System.out.println(thisJoinPointStaticPart.getSignature()); + } +} diff --git a/tests/features190/efficientTJP/Fields2.java b/tests/features190/efficientTJP/Fields2.java new file mode 100644 index 000000000..0a8aed75c --- /dev/null +++ b/tests/features190/efficientTJP/Fields2.java @@ -0,0 +1,40 @@ +public class Fields2 { + int a = 1; + String s = "hello"; + double d = 1.0d; + boolean b = true; + + short ps = (short)1; + float fs = 1.0f; + long ls = 1L; + byte bs = (byte)3; + char cs = 'a'; + + + Inner obj = new Inner(); + static int as = 1; + static String ss = "hello"; + static double ds = 1.0d; + static Inner objs = new Inner(); + + public static void main(String []argv) { + Fields2 f = new Fields2(); + f.a = 2; + f.ps = (short)3; + f.d = 2.0d; + f.obj = new Inner(); + f.s = "helo"; + f.fs = 4f; + f.ls = 3L; + f.bs = (byte)23; + f.cs = 'a'; + } + + static class Inner {} +} + +aspect X { + before(): within(Fields2) && set(* *) && withincode(* main(..)){ + System.out.println(thisJoinPointStaticPart.getSignature()); + } +} diff --git a/tests/features190/efficientTJP/FieldsE.java b/tests/features190/efficientTJP/FieldsE.java new file mode 100644 index 000000000..51bc923fa --- /dev/null +++ b/tests/features190/efficientTJP/FieldsE.java @@ -0,0 +1,46 @@ +public class FieldsE { + int a = 1; + String s = "hello"; + double d = 1.0d; + boolean b = true; + + short ps = (short)1; + float fs = 1.0f; + long ls = 1L; + byte bs = (byte)3; + char cs = 'a'; + + + Inner obj = new Inner(); + static int as = 1; + static String ss = "hello"; + static double ds = 1.0d; + static Inner objs = new Inner(); + + public static void main(String []argv) { + FieldsE f = new FieldsE(); + int a2 = f.a; + String s2 = f.s; + double d2 = f.d; + Inner obj2 = f.obj; + + short ps2 = f.ps; + float fs2 = f.fs; + long ls2 = f.ls; + byte bs2 = f.bs; + char cs2 = f.cs; + + int a3 = as; + String s3 = ss; + double d3 = ds; + Inner obj3 = objs; + } + + static class Inner {} +} + +aspect X { + before(): within(FieldsE) && get(* *) { + System.out.println(thisEnclosingJoinPointStaticPart.getSignature()); + } +} diff --git a/tests/features190/efficientTJP/Four.java b/tests/features190/efficientTJP/Four.java new file mode 100644 index 000000000..9857c8c62 --- /dev/null +++ b/tests/features190/efficientTJP/Four.java @@ -0,0 +1,21 @@ +public class Four { + public static void main(String []argv) { + new Four().run(); + } + + public void run() { + try { + System.out.println("run() running"); + throw new IllegalStateException(); + } catch (Throwable t) { + System.out.println("caught something"); + } + } + +} + +aspect X { + before(Throwable t): handler(Throwable) && args(t) { + System.out.println(thisJoinPointStaticPart.getSignature()); + } +} diff --git a/tests/features190/efficientTJP/FourA.java b/tests/features190/efficientTJP/FourA.java new file mode 100644 index 000000000..47694dcbf --- /dev/null +++ b/tests/features190/efficientTJP/FourA.java @@ -0,0 +1,21 @@ +public class FourA { + public static void main(String []argv) { + new FourA().run(); + } + + public void run() { + try { + System.out.println("run() running"); + throw new IllegalStateException(); + } catch (Throwable t) { + System.out.println("caught something"); + } + } + +} + +aspect X { + before(Throwable t): handler(Throwable) && args(t) { + System.out.println(thisEnclosingJoinPointStaticPart.getSignature()); + } +} diff --git a/tests/features190/efficientTJP/Init.java b/tests/features190/efficientTJP/Init.java new file mode 100644 index 000000000..200ce18ce --- /dev/null +++ b/tests/features190/efficientTJP/Init.java @@ -0,0 +1,24 @@ +public class Init { + public static void main(String []argv) { + new A(); + new B(); + } +} + +class A {} +class B {} + +aspect X { + before(): preinitialization(A.new(..)) && !within(X) { + System.out.println(thisJoinPointStaticPart.getSignature()); + } + before(): preinitialization(A.new(..)) && !within(X) { + System.out.println(thisEnclosingJoinPointStaticPart.getSignature()); + } + before(): initialization(B.new(..)) && !within(X) { + System.out.println(thisJoinPointStaticPart.getSignature()); + } + before(): initialization(B.new(..)) && !within(X) { + System.out.println(thisEnclosingJoinPointStaticPart.getSignature()); + } +} diff --git a/tests/features190/efficientTJP/One.java b/tests/features190/efficientTJP/One.java new file mode 100644 index 000000000..4fafcdaf7 --- /dev/null +++ b/tests/features190/efficientTJP/One.java @@ -0,0 +1,12 @@ +public class One { + public static void main(String []argv) { + System.out.println("One running"); + } +} + +aspect X { + void around(): execution(* main(..)) { + System.out.println(thisJoinPoint.getSignature()); + proceed(); + } +} diff --git a/tests/features190/efficientTJP/Three.java b/tests/features190/efficientTJP/Three.java new file mode 100644 index 000000000..479c7f7d1 --- /dev/null +++ b/tests/features190/efficientTJP/Three.java @@ -0,0 +1,19 @@ +public class Three { + public static void main(String []argv) { + System.out.println("Three running"); + new Three(); + new Three("abc"); + new Three(1,"abc"); + } + + Three() {} + Three(String s) {} + Three(int i, String s) {} +} + +aspect X { + void around(): execution(new(..)) && !within(X) { + System.out.println(thisJoinPointStaticPart.getSignature()); + proceed(); + } +} diff --git a/tests/features190/efficientTJP/ThreeA.java b/tests/features190/efficientTJP/ThreeA.java new file mode 100644 index 000000000..e3ffac941 --- /dev/null +++ b/tests/features190/efficientTJP/ThreeA.java @@ -0,0 +1,19 @@ +public class ThreeA { + public static void main(String []argv) { + System.out.println("ThreeA running"); + new ThreeA(); + new ThreeA("abc"); + new ThreeA(1,"abc"); + } + + ThreeA() {} + ThreeA(String s) {} + ThreeA(int i, String s) {} +} + +aspect X { + void around(): execution(new(..)) && !within(X) { + System.out.println(thisEnclosingJoinPointStaticPart.getSignature()); + proceed(); + } +} diff --git a/tests/features190/efficientTJP/Two.java b/tests/features190/efficientTJP/Two.java new file mode 100644 index 000000000..2d5d1da69 --- /dev/null +++ b/tests/features190/efficientTJP/Two.java @@ -0,0 +1,12 @@ +public class Two { + public static void main(String []argv) { + System.out.println("Two running"); + } +} + +aspect X { + void around(): execution(* main(..)) { + System.out.println(thisEnclosingJoinPointStaticPart.getSignature()); + proceed(); + } +} diff --git a/tests/src/org/aspectj/systemtest/ajc151/NewarrayJoinpointTests.java b/tests/src/org/aspectj/systemtest/ajc151/NewarrayJoinpointTests.java index 9c92f8488..9654c04dd 100644 --- a/tests/src/org/aspectj/systemtest/ajc151/NewarrayJoinpointTests.java +++ b/tests/src/org/aspectj/systemtest/ajc151/NewarrayJoinpointTests.java @@ -13,13 +13,13 @@ package org.aspectj.systemtest.ajc151; import java.io.File; import java.util.List; -import junit.framework.Test; - import org.aspectj.asm.AsmManager; import org.aspectj.asm.IProgramElement; import org.aspectj.asm.IRelationship; import org.aspectj.testing.XMLBasedAjcTestCase; +import junit.framework.Test; + /* * The design: * @@ -59,6 +59,15 @@ public class NewarrayJoinpointTests extends XMLBasedAjcTestCase { runTest("thisjoinpoint"); } + public void testThisJoinPoint19() { + try { + System.setProperty("ASPECTJ_OPTS", "-Xajruntimetarget:1.9"); + runTest("thisjoinpoint"); + } finally { + System.setProperty("ASPECTJ_OPTS", ""); + } + } + public void testDifferentAdviceKinds() { runTest("different advice kinds"); } @@ -105,9 +114,9 @@ public class NewarrayJoinpointTests extends XMLBasedAjcTestCase { assertTrue("Couldnt find 'Five' type in the model", ipe != null); List<IProgramElement> kids = ipe.getChildren(); assertTrue("Couldn't find 'main' method in the 'Five' type", kids != null && kids.size() == 1); - List<IProgramElement> codenodes = ((IProgramElement) kids.get(0)).getChildren(); + List<IProgramElement> codenodes = kids.get(0).getChildren(); assertTrue("Couldn't find nodes below 'main' method", codenodes != null && codenodes.size() == 1); - IProgramElement arrayCtorCallNode = (IProgramElement) codenodes.get(0); + IProgramElement arrayCtorCallNode = codenodes.get(0); String exp = "constructor-call(void java.lang.Integer[].<init>(int))"; assertTrue("Expected '" + exp + "' but found " + arrayCtorCallNode.toString(), arrayCtorCallNode.toString().equals(exp)); List<IRelationship> rels = AsmManager.lastActiveStructureModel.getRelationshipMap().get(arrayCtorCallNode); @@ -119,6 +128,7 @@ public class NewarrayJoinpointTests extends XMLBasedAjcTestCase { return XMLBasedAjcTestCase.loadSuite(NewarrayJoinpointTests.class); } + @Override protected File getSpecFile() { return getClassResource("newarray_joinpoint.xml"); } diff --git a/tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java b/tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java index 2ebc12e7c..d0f7734f3 100644 --- a/tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java +++ b/tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java @@ -20,7 +20,7 @@ public class AllTestsAspectJ190 { // $JUnit-BEGIN$ suite.addTest(Ajc190Tests.suite()); suite.addTest(SanityTests19.suite()); -// suite.addTest(EfficientTJPTests.suite()); + suite.addTest(EfficientTJPTests.suite()); suite.addTest(ModuleTests.suite()); suite.addTest(Annotations.suite()); // $JUnit-END$ diff --git a/tests/src/org/aspectj/systemtest/ajc190/EfficientTJPTests.java b/tests/src/org/aspectj/systemtest/ajc190/EfficientTJPTests.java new file mode 100644 index 000000000..3564f9469 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/EfficientTJPTests.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2018 Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.aspectj.systemtest.ajc190; + +import java.io.File; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.testing.XMLBasedAjcTestCase; + +import junit.framework.Assert; +import junit.framework.Test; + +/** + * + * @author Andy Clement + */ +public class EfficientTJPTests extends XMLBasedAjcTestCase { + + public void testThisJoinPointMethodExecution() { + // Test setting it via sys props rather than passing the option directly + try { + System.setProperty("ASPECTJ_OPTS", "-Xajruntimetarget:1.9"); + runTest("tjp 1"); + checkPreClinitContains("One","Factory.makeMethodSJP"); + } finally { + System.setProperty("ASPECTJ_OPTS", ""); + } + } + + public void testThisEnclosingJoinPointMethodExecution() { + runTest("tjp 2"); + checkPreClinitContains("Two","Factory.makeMethodESJP"); + } + + public void testThisJoinPointConstructorExecution() { + runTest("tjp 3"); + checkPreClinitContains("Three","Factory.makeConstructorSJP"); + } + + public void testThisEnclosingJoinPointConstructorExecution() { + runTest("tjp 3a"); + checkPreClinitContains("ThreeA","Factory.makeConstructorESJP"); + } + + public void testThisJoinPointHandler() { + runTest("tjp 4"); + checkPreClinitContains("Four","Factory.makeCatchClauseSJP"); + } + + public void testThisEnclosingJoinPointHandler() { + runTest("tjp 4a"); + checkPreClinitContains("FourA","Factory.makeMethodESJP"); + } + + public void testThisJoinPointFieldGet() { + runTest("tjp get fields"); + checkPreClinitContains("Fields","Factory.makeFieldSJP"); + } + + public void testThisEnclosingJoinPointFieldGet() { + runTest("tjp get fieldsE"); + checkPreClinitContains("FieldsE","Factory.makeMethodESJP"); + } + + public void testThisJoinPointFieldSet() { + runTest("tjp set fields"); + checkPreClinitContains("Fields2","Factory.makeFieldSJP"); + } + + public void testThisJoinPointClinit() { + runTest("tjp clinit"); + checkPreClinitContains("Clinit","Factory.makeInitializerSJP"); + } + + public void testThisEnclosingJoinPointClinit() { + runTest("tejp clinit"); + checkPreClinitContains("ClinitE","Factory.makeInitializerESJP"); + } + + public void testThisJoinPointAdvice() { + // covers enclosing joinpoint too + runTest("tjp advice"); + checkPreClinitContains("X","Factory.makeAdviceESJP"); + } + + public void testThisJoinPointInitialization() { + runTest("tjp init"); + checkPreClinitContains("A","Factory.makeConstructorESJP"); + checkPreClinitContains("B","Factory.makeConstructorESJP"); + } + + // /////////////////////////////////////// + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(EfficientTJPTests.class); + } + + @Override + protected File getSpecFile() { + return getClassResource("features190.xml"); + } + + public void checkPreClinitContains(String classname, String text) { + try { + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), classname); + Method[] meths = jc.getMethods(); + for (int i = 0; i < meths.length; i++) { + Method method = meths[i]; + if (method.getName().equals("ajc$preClinit")) { + String code = method.getCode().getCodeString(); + assertTrue("Expected to contain '"+text+"':\n"+code,code.contains(text)); + return; + } + } + Assert.fail("Unable to find ajc$preClinit in class "+classname); + } catch (Exception e) { + Assert.fail(e.toString()); + } + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc190/features190.xml b/tests/src/org/aspectj/systemtest/ajc190/features190.xml new file mode 100644 index 000000000..1fb931e97 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc190/features190.xml @@ -0,0 +1,172 @@ +<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]> + +<suite> + + <ajc-test dir="features190/efficientTJP" title="tjp 1"> + <compile files="One.java" options="-1.8"/> + <run class="One"> + <stdout> + <line text="void One.main(String[])"/> + <line text="One running"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp 2"> + <compile files="Two.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="Two"> + <stdout> + <line text="void Two.main(String[])"/> + <line text="Two running"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp 3"> + <compile files="Three.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="Three"> + <stdout> + <line text="Three running"/> + <line text="Three()"/> + <line text="Three(String)"/> + <line text="Three(int, String)"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp 3a"> + <compile files="ThreeA.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="ThreeA"> + <stdout> + <line text="ThreeA running"/> + <line text="ThreeA()"/> + <line text="ThreeA(String)"/> + <line text="ThreeA(int, String)"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp 4"> + <compile files="Four.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="Four"> + <stdout> + <line text="run() running"/> + <line text="catch(Throwable)"/> + <line text="caught something"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp 4a"> + <compile files="FourA.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="FourA"> + <stdout> + <line text="run() running"/> + <line text="void FourA.run()"/> + <line text="caught something"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp get fields"> + <compile files="Fields.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="Fields"> + <stdout> + <line text="int Fields.a"/> + <line text="String Fields.s"/> + <line text="double Fields.d"/> + <line text="Fields.Inner Fields.obj"/> + <line text="short Fields.ps"/> + <line text="float Fields.fs"/> + <line text="long Fields.ls"/> + <line text="byte Fields.bs"/> + <line text="char Fields.cs"/> + <line text="int Fields.as"/> + <line text="String Fields.ss"/> + <line text="double Fields.ds"/> + <line text="Fields.Inner Fields.objs"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp get fieldsE"> + <compile files="FieldsE.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="FieldsE"> + <stdout> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + <line text="void FieldsE.main(String[])"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp set fields"> + <compile files="Fields2.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="Fields2"> + <stdout> + <line text="int Fields2.a"/> + <line text="short Fields2.ps"/> + <line text="double Fields2.d"/> + <line text="Fields2.Inner Fields2.obj"/> + <line text="String Fields2.s"/> + <line text="float Fields2.fs"/> + <line text="long Fields2.ls"/> + <line text="byte Fields2.bs"/> + <line text="char Fields2.cs"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp clinit"> + <compile files="Clinit.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="Clinit"> + <stdout> + <line text="Clinit.<clinit>"/> + <line text="Clinit.Inner.<clinit>"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tejp clinit"> + <compile files="ClinitE.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="ClinitE"> + <stdout> + <line text="ClinitE.<clinit>"/> + <line text="ClinitE.Inner.<clinit>"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp advice"> + <compile files="Advice.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="Advice"> + <stdout> + <line text="tjp:void X.before()"/> + <line text="tejp:void X.before()"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features190/efficientTJP" title="tjp init"> + <compile files="Init.java" options="-Xajruntimetarget:1.9 -1.8"/> + <run class="Init"> + <stdout> + <line text="A()"/> + <line text="A()"/> + <line text="B()"/> + <line text="B()"/> + </stdout> + </run> + </ajc-test> + +</suite> diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java index 395e07e10..4ade1e125 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java @@ -723,26 +723,32 @@ public class BcelWorld extends World implements Repository { // / The repository interface methods + @Override public JavaClass findClass(String className) { return lookupJavaClass(classPath, className); } + @Override public JavaClass loadClass(String className) throws ClassNotFoundException { return lookupJavaClass(classPath, className); } + @Override public void storeClass(JavaClass clazz) { // doesn't need to do anything } + @Override public void removeClass(JavaClass clazz) { throw new RuntimeException("Not implemented"); } + @Override public JavaClass loadClass(Class clazz) throws ClassNotFoundException { throw new RuntimeException("Not implemented"); } + @Override public void clear() { delegate.clear(); // throw new RuntimeException("Not implemented"); @@ -1291,10 +1297,12 @@ public class BcelWorld extends World implements Repository { } + @Override public TypeMap getTypeMap() { return typeMap; } + @Override public boolean isLoadtimeWeaving() { return false; } @@ -1306,6 +1314,7 @@ public class BcelWorld extends World implements Repository { typeDelegateResolvers.add(typeDelegateResolver); } + @Override public void classWriteEvent(char[][] compoundName) { typeMap.classWriteEvent(new String(CharOperation.concatWith(compoundName, '.'))); } diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java index 24240d7ca..95ef524b5 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java @@ -53,15 +53,16 @@ import org.aspectj.apache.bcel.generic.Type; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.SourceLocation; -import org.aspectj.util.LangUtil; import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjAttribute.WeaverState; import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; import org.aspectj.weaver.BCException; import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberKind; import org.aspectj.weaver.NameMangler; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.RuntimeVersion; import org.aspectj.weaver.Shadow; import org.aspectj.weaver.SignatureUtils; import org.aspectj.weaver.TypeVariable; @@ -80,6 +81,45 @@ import org.aspectj.weaver.bcel.asm.StackMapAdder; */ public final class LazyClassGen { + private static final Type[] ARRAY_7STRING_INT = new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING, + Type.STRING, Type.STRING, Type.INT }; + + private static final Type[] ARRAY_8STRING_INT = new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING, + Type.STRING, Type.STRING, Type.STRING, Type.INT }; + + private static final Type[] PARAMSIGNATURE_MAKESJP_METHOD = new Type[] { + Type.STRING, Type.INT, Type.STRING, Type.CLASS, Type.CLASS_ARRAY, Type.STRING_ARRAY, Type.CLASS_ARRAY, Type.CLASS, Type.INT + }; + + private static final Type[] PARAMSIGNATURE_MAKESJP_CONSTRUCTOR = new Type[] { + Type.STRING, Type.INT, Type.CLASS, Type.CLASS_ARRAY, Type.STRING_ARRAY, Type.CLASS_ARRAY, Type.INT + }; + + private static final Type[] PARAMSIGNATURE_MAKESJP_CATCHCLAUSE = new Type[] { + Type.STRING, Type.CLASS, Type.CLASS, Type.STRING, Type.INT + }; + + private static final Type[] PARAMSIGNATURE_MAKESJP_FIELD = new Type[] { + Type.STRING, Type.INT, Type.STRING, Type.CLASS, Type.CLASS, Type.INT + }; + + private static final Type[] PARAMSIGNATURE_MAKESJP_INITIALIZER = new Type[] { + Type.STRING, Type.INT, Type.CLASS, Type.INT + }; + + private static final Type[] PARAMSIGNATURE_MAKESJP_MONITOR = new Type[] { + Type.STRING, Type.CLASS, Type.INT + }; + + private static final Type[] PARAMSIGNATURE_MAKESJP_ADVICE = new Type[] { + Type.STRING, Type.INT, Type.STRING, Type.CLASS, Type.CLASS_ARRAY, Type.STRING_ARRAY, + Type.CLASS_ARRAY, Type.CLASS, Type.INT + }; + + + + + private static final int ACC_SYNTHETIC = 0x1000; private static final String[] NO_STRINGS = new String[0]; @@ -1232,6 +1272,7 @@ public final class LazyClassGen { List<Map.Entry<BcelShadow, Field>> entries = new ArrayList<Map.Entry<BcelShadow, Field>>(tjpFields.entrySet()); Collections.sort(entries, new Comparator<Map.Entry<BcelShadow, Field>>() { + @Override public int compare(Map.Entry<BcelShadow, Field> a, Map.Entry<BcelShadow, Field> b) { return (a.getValue()).getName().compareTo((b.getValue()).getName()); } @@ -1253,6 +1294,10 @@ public final class LazyClassGen { } private void initializeTjp(InstructionFactory fact, InstructionList list, Field field, BcelShadow shadow) { + if (world.getTargetAspectjRuntimeLevel() == RuntimeVersion.V1_9) { + initializeTjpOptimal(fact, list, field, shadow); + return; + } boolean fastSJP = false; // avoid fast SJP if it is for an enclosing joinpoint boolean isFastSJPAvailable = shadow.getWorld().isTargettingRuntime1_6_10() @@ -1274,9 +1319,7 @@ public final class LazyClassGen { String signatureMakerName = SignatureUtils.getSignatureMakerName(sig); ObjectType signatureType = new ObjectType(SignatureUtils.getSignatureType(sig)); UnresolvedType[] exceptionTypes = null; - if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We - // didn't have optimized - // factory methods in 1.2 + if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have optimized factory methods in 1.2 list.append(InstructionFactory.PUSH(cp, SignatureUtils.getSignatureString(sig, shadow.getWorld()))); list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY1, Constants.INVOKEVIRTUAL)); @@ -1370,6 +1413,7 @@ public final class LazyClassGen { list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY2, Constants.INVOKEVIRTUAL)); } else { + // TODO looks like this block is unused code list.append(InstructionFactory.PUSH(cp, SignatureUtils.getSignatureString(sig, shadow.getWorld()))); list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY1, Constants.INVOKEVIRTUAL)); @@ -1415,10 +1459,208 @@ public final class LazyClassGen { } } - private static final Type[] ARRAY_7STRING_INT = new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING, - Type.STRING, Type.STRING, Type.INT }; - private static final Type[] ARRAY_8STRING_INT = new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING, - Type.STRING, Type.STRING, Type.STRING, Type.INT }; + public String getFactoryMethod(Field field, BcelShadow shadow) { + StringBuilder b = new StringBuilder(); + b.append("make"); + MemberKind kind = shadow.getSignature().getKind(); + if (kind.equals(Member.METHOD)) { + b.append("Method"); + } else if (kind.equals(Member.CONSTRUCTOR)) { + b.append("Constructor"); + } else if (kind.equals(Member.HANDLER)) { + b.append("CatchClause"); + } else if (kind.equals(Member.FIELD)) { + b.append("Field"); + } else if (kind.equals(Member.STATIC_INITIALIZATION)) { + b.append("Initializer"); + } else if (kind.equals(Member.MONITORENTER)) { + b.append("Lock"); + } else if (kind.equals(Member.MONITOREXIT)) { + b.append("Unlock"); + } else if (kind.equals(Member.ADVICE)) { + b.append("Advice"); + } else { + throw new IllegalStateException(kind.toString()); + } + if (staticTjpType.equals(field.getType())) { + b.append("SJP"); + } else if (enclosingStaticTjpType.equals(field.getType())) { + b.append("ESJP"); + } + return b.toString(); + } + + /** + * Generate optimal joinpoint initialization code. + * + * As of version 1.9.1 the runtime includes new factory methods for joinpoints that take classes, not strings + * and using them requires different code generation. Using these instead of the old ones means we can avoid + * deferred classloading for these types. By using the LDC instruction that loads classes, it also means + * anything modifying woven code and changing type names will also pick up on these references. + */ + private void initializeTjpOptimal(InstructionFactory fact, InstructionList list, Field field, BcelShadow shadow) { + list.append(InstructionFactory.createLoad(factoryType, 0)); + pushString(list, shadow.getKind().getName()); + String factoryMethod = getFactoryMethod(field, shadow); + Member sig = shadow.getSignature(); + BcelWorld w = shadow.getWorld(); + + if (sig.getKind().equals(Member.METHOD)) { + pushInt(list, sig.getModifiers(w)); + pushString(list, sig.getName()); + pushClass(list, sig.getDeclaringType()); + pushClasses(list, sig.getParameterTypes()); + pushStrings(list, sig.getParameterNames(w)); + pushClasses(list, sig.getExceptions(w)); + pushClass(list, sig.getReturnType()); + pushInt(list, shadow.getSourceLine()); + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), + PARAMSIGNATURE_MAKESJP_METHOD, Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.CONSTRUCTOR)) { + if (w.isJoinpointArrayConstructionEnabled() && sig.getDeclaringType().isArray()) { + pushInt(list, Modifier.PUBLIC); + pushClass(list, sig.getDeclaringType()); + pushClasses(list, sig.getParameterTypes()); + pushStrings(list, null); + pushClasses(list, null); + } else { + pushInt(list, sig.getModifiers(w)); + pushClass(list, sig.getDeclaringType()); + pushClasses(list, sig.getParameterTypes()); + pushStrings(list, sig.getParameterNames(w)); + pushClasses(list, sig.getExceptions(w)); + } + pushInt(list, shadow.getSourceLine()); + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), + PARAMSIGNATURE_MAKESJP_CONSTRUCTOR, Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.HANDLER)) { + pushClass(list, sig.getDeclaringType()); + pushClass(list, sig.getParameterTypes()[0]); + String pname = null; + String[] pnames = sig.getParameterNames(w); + if (pnames != null && pnames.length>0) { + pname = pnames[0]; + } + pushString(list, pname); + pushInt(list, shadow.getSourceLine()); + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), + PARAMSIGNATURE_MAKESJP_CATCHCLAUSE, Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.FIELD)) { + pushInt(list, sig.getModifiers(w)); + pushString(list, sig.getName()); + // see pr227401 + UnresolvedType dType = sig.getDeclaringType(); + if (dType.getTypekind() == TypeKind.PARAMETERIZED || dType.getTypekind() == TypeKind.GENERIC) { + dType = sig.getDeclaringType().resolve(world).getGenericType(); + } + pushClass(list, dType); + pushClass(list, sig.getReturnType()); + pushInt(list,shadow.getSourceLine()); + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), + PARAMSIGNATURE_MAKESJP_FIELD, Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.STATIC_INITIALIZATION)) { + pushInt(list, sig.getModifiers(w)); + pushClass(list, sig.getDeclaringType()); + pushInt(list, shadow.getSourceLine()); + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), + PARAMSIGNATURE_MAKESJP_INITIALIZER, Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.MONITORENTER)) { + pushClass(list, sig.getDeclaringType()); + pushInt(list, shadow.getSourceLine()); + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), + PARAMSIGNATURE_MAKESJP_MONITOR, Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.MONITOREXIT)) { + pushClass(list, sig.getDeclaringType()); + pushInt(list, shadow.getSourceLine()); + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), + PARAMSIGNATURE_MAKESJP_MONITOR, Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.ADVICE)) { + pushInt(list, sig.getModifiers(w)); + pushString(list, sig.getName()); + pushClass(list, sig.getDeclaringType()); + pushClasses(list, sig.getParameterTypes()); + pushStrings(list, sig.getParameterNames(w)); + pushClasses(list, sig.getExceptions(w)); + pushClass(list, sig.getReturnType()); + pushInt(list, shadow.getSourceLine()); + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), + PARAMSIGNATURE_MAKESJP_ADVICE, Constants.INVOKEVIRTUAL)); + } else { + throw new IllegalStateException("not sure what to do: "+shadow); + } + list.append(fact.createFieldAccess(getClassName(), field.getName(), field.getType(), Constants.PUTSTATIC)); + } + + private void pushStrings(InstructionList list, String[] strings) { + // Build an array loaded with the strings + if (strings == null || strings.length == 0) { + list.append(InstructionFactory.ACONST_NULL); + } else { + list.append(InstructionFactory.PUSH(cp, strings.length)); + list.append(fact.createNewArray(Type.STRING, (short)1)); + for (int s=0;s<strings.length;s++) { + list.append(InstructionFactory.DUP); + list.append(InstructionFactory.PUSH(cp, s)); + list.append(InstructionFactory.PUSH(cp, strings[s])); + list.append(InstructionFactory.AASTORE); + } + } + } + + private void pushClass(InstructionList list, UnresolvedType type) { + if (type.isPrimitiveType()) { + if (type.getSignature().equals("I")) { + list.append(fact.createGetStatic("java/lang/Integer","TYPE", Type.CLASS)); + } else if (type.getSignature().equals("D")) { + list.append(fact.createGetStatic("java/lang/Double","TYPE", Type.CLASS)); + } else if (type.getSignature().equals("S")) { + list.append(fact.createGetStatic("java/lang/Short","TYPE", Type.CLASS)); + } else if (type.getSignature().equals("J")) { + list.append(fact.createGetStatic("java/lang/Long","TYPE", Type.CLASS)); + } else if (type.getSignature().equals("F")) { + list.append(fact.createGetStatic("java/lang/Float","TYPE", Type.CLASS)); + } else if (type.getSignature().equals("C")) { + list.append(fact.createGetStatic("java/lang/Character","TYPE", Type.CLASS)); + } else if (type.getSignature().equals("B")) { + list.append(fact.createGetStatic("java/lang/Byte","TYPE", Type.CLASS)); + } else if (type.getSignature().equals("Z")) { + list.append(fact.createGetStatic("java/lang/Boolean","TYPE", Type.CLASS)); + } else if (type.getSignature().equals("V")) { + list.append(InstructionFactory.ACONST_NULL); + } + return; + } + String classString = makeLdcClassString(type); + if (classString == null) { + list.append(InstructionFactory.ACONST_NULL); + } else { + list.append(fact.PUSHCLASS(cp, classString)); + } + } + + private void pushClasses(InstructionList list, UnresolvedType[] types) { + // Build an array loaded with the class objects + if (types == null || types.length == 0) { + list.append(InstructionFactory.ACONST_NULL); + } else { + list.append(InstructionFactory.PUSH(cp, types.length)); + list.append(fact.createNewArray(Type.CLASS, (short)1)); + for (int t=0;t<types.length;t++) { + list.append(InstructionFactory.DUP); + list.append(InstructionFactory.PUSH(cp, t)); + pushClass(list, types[t]); + list.append(InstructionFactory.AASTORE); + } + } + } + + private final void pushString(InstructionList list, String string) { + list.append(InstructionFactory.PUSH(cp, string)); + } + + private final void pushInt(InstructionList list, int value) { + list.append(InstructionFactory.PUSH(cp, value)); + } protected String makeString(int i) { return Integer.toString(i, 16); // ??? expensive @@ -1438,6 +1680,24 @@ public final class LazyClassGen { } } } + + protected String makeLdcClassString(UnresolvedType type) { + if (type.isVoid() || type.isPrimitiveType()) { + return null; + } + if (type.isArray()) { + return type.getSignature(); + } else { + if (type.isParameterizedType()) { + type = type.getRawType(); + } + String signature = type.getSignature(); + if (signature.length() ==1 ) { + return signature; + } + return signature.substring(1,signature.length()-1); + } + } protected String makeString(UnresolvedType[] types) { if (types == null) { |