aboutsummaryrefslogtreecommitdiffstats
path: root/tests/bugs198
diff options
context:
space:
mode:
authorAlexander Kriegisch <Alexander@Kriegisch.name>2022-01-08 16:06:51 +0700
committerAlexander Kriegisch <Alexander@Kriegisch.name>2022-01-08 16:06:51 +0700
commitde63b63d8264efc9c81aa667546d028859b7a90c (patch)
tree75506eddf1ffe6d81780f091dae73044a3f072f2 /tests/bugs198
parent92779d0829d41d55cae300d4d4d5a67cff72916d (diff)
downloadaspectj-de63b63d8264efc9c81aa667546d028859b7a90c.tar.gz
aspectj-de63b63d8264efc9c81aa667546d028859b7a90c.zip
Add test for Java 11 constant-dynamic
Relates to #68. Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
Diffstat (limited to 'tests/bugs198')
-rw-r--r--tests/bugs198/github_68/Application.java20
-rw-r--r--tests/bugs198/github_68/Generator.java67
-rw-r--r--tests/bugs198/github_68/MyAspect.aj5
-rw-r--r--tests/bugs198/github_68/condy.jarbin0 -> 515 bytes
4 files changed, 92 insertions, 0 deletions
diff --git a/tests/bugs198/github_68/Application.java b/tests/bugs198/github_68/Application.java
new file mode 100644
index 000000000..47eeaa4f4
--- /dev/null
+++ b/tests/bugs198/github_68/Application.java
@@ -0,0 +1,20 @@
+import java.lang.invoke.ConstantBootstraps;
+import java.util.concurrent.Callable;
+
+public class Application {
+ public static void main(String[] args) throws Exception {
+ Callable<?> first = new CondyCallable();
+ Callable<?> second = new CondyCallable();
+ if (!(first.call() == second.call()))
+ throw new RuntimeException("Non-identical ConstantDynamic values (should never happen)");
+ }
+
+ /**
+ * Class {@link CondyCallable} dispatches to this constructor via {@link ConstantBootstraps#invoke}
+ * in order to initialise a dynamic constant value. The constructor should be executed exactly once,
+ * no matter how many times {@link CondyCallable#call} is called.
+ */
+ public Application() {
+ System.out.println("Sample instance created");
+ }
+}
diff --git a/tests/bugs198/github_68/Generator.java b/tests/bugs198/github_68/Generator.java
new file mode 100644
index 000000000..ea34c5b3b
--- /dev/null
+++ b/tests/bugs198/github_68/Generator.java
@@ -0,0 +1,67 @@
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * This class was created by ASM-ifying a class generated by Byte Buddy.
+ * Its purpose it to create a class <tt>CondyCallable</tt> making use of
+ * dynamic class-file constants, a Java 11 feature introduced by JEP 309.
+ *
+ * @see https://openjdk.java.net/jeps/309
+ */
+public class Generator implements Opcodes {
+
+ private static final String CLASS_FILE = "CondyCallable.class";
+
+ public static void main(String[] args) throws IOException {
+ try (FileOutputStream fos = new FileOutputStream(CLASS_FILE)) {
+ fos.write(getClassBytes());
+ }
+ System.out.println(CLASS_FILE + " generated successfully");
+ }
+
+ private static byte[] getClassBytes() {
+ ClassWriter classWriter = new ClassWriter(0);
+ classWriter.visit(V11, ACC_PUBLIC | ACC_SUPER, "CondyCallable", null, "java/lang/Object", new String[] { "java/util/concurrent/Callable" });
+ createDefaultConstructor(classWriter);
+ createMethod_call(classWriter);
+ classWriter.visitEnd();
+ return classWriter.toByteArray();
+ }
+
+ private static void createDefaultConstructor(ClassWriter classWriter) {
+ MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+
+ private static void createMethod_call(ClassWriter classWriter) {
+ MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "call", "()Ljava/lang/Object;", null, new String[] { "java/lang/Exception" });
+ methodVisitor.visitCode();
+ methodVisitor.visitLdcInsn(
+ // Create constant-dynamic instruction
+ new ConstantDynamic(
+ // Dummy name
+ "_",
+ // Constant type
+ "LApplication;",
+ // Bootstrap method: ConstantBootstraps::invoke, dispatching to an existing method/constructor
+ new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/ConstantBootstraps", "invoke", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;", false),
+ // Bootstrap method arguments: here we simply dispatch to the constructor of class Application
+ new Handle(Opcodes.H_NEWINVOKESPECIAL, "Application", "<init>", "()V", false))
+ );
+ methodVisitor.visitInsn(ARETURN);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+
+}
diff --git a/tests/bugs198/github_68/MyAspect.aj b/tests/bugs198/github_68/MyAspect.aj
new file mode 100644
index 000000000..1a329dfa0
--- /dev/null
+++ b/tests/bugs198/github_68/MyAspect.aj
@@ -0,0 +1,5 @@
+public aspect MyAspect {
+ before() : execution(*.new(..)) && !within(MyAspect) {
+ System.out.println(thisJoinPoint);
+ }
+}
diff --git a/tests/bugs198/github_68/condy.jar b/tests/bugs198/github_68/condy.jar
new file mode 100644
index 000000000..75fe7e5b8
--- /dev/null
+++ b/tests/bugs198/github_68/condy.jar
Binary files differ