Move Twr test to java 9 package
Change-Id: Ib89e36424acf82fcfe3f3ecaaec7aeaa7643fe02
diff --git a/src/test/examplesJava9/twr/twraddsuppressed/TwrSuppressedExceptionsTest.java b/src/test/examplesJava9/twr/twraddsuppressed/TwrSuppressedExceptionsTest.java
new file mode 100644
index 0000000..573fc99
--- /dev/null
+++ b/src/test/examplesJava9/twr/twraddsuppressed/TwrSuppressedExceptionsTest.java
@@ -0,0 +1,160 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package twr.twraddsuppressed;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.DesugarTestConfiguration;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.utils.IntBox;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import twr.twraddsuppressed.asm.TestClass$MyClosableDump;
+import twr.twraddsuppressed.asm.TestClassDump;
+
+@RunWith(Parameterized.class)
+public class TwrSuppressedExceptionsTest extends TestBase {
+
+ private static final String TEST_CLASS = "twr.twraddsuppressed.TestClass";
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters()
+ .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+ .withDexRuntimes()
+ .withAllApiLevelsAlsoForCf()
+ .build();
+ }
+
+ public boolean runtimeHasSuppressedExceptionsSupport() {
+ // TODO(b/214239152): Update this if desugaring is changed.
+ // Despite 4.0.4 being API level 15 and add suppressed being officially added in 19 it is
+ // actually implemented. Thus, the backport implementation will use the functionality and run
+ // as expected by RI.
+ return parameters.isCfRuntime()
+ || parameters.getDexRuntimeVersion().isNewerThanOrEqual(Version.V4_0_4);
+ }
+
+ public boolean apiLevelHasSuppressedExceptionsSupport(boolean isDesugaring) {
+ return !isDesugaring
+ || parameters
+ .getApiLevel()
+ .isGreaterThanOrEqualTo(apiLevelWithSuppressedExceptionsSupport());
+ }
+
+ public boolean apiLevelHasTwrCloseResourceSupport(boolean isDesugaring) {
+ return !isDesugaring
+ || parameters.getApiLevel().isGreaterThanOrEqualTo(apiLevelWithTwrCloseResourceSupport());
+ }
+
+ public List<byte[]> getProgramInputs() throws Exception {
+ return ImmutableList.of(TestClassDump.dump(), TestClass$MyClosableDump.dump());
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ testForDesugaring(parameters)
+ .addProgramClassFileData(getProgramInputs())
+ .run(parameters.getRuntime(), TEST_CLASS)
+ .assertSuccessWithOutput(
+ runtimeHasSuppressedExceptionsSupport() ? StringUtils.lines("CLOSE") : "NONE")
+ .inspectIf(
+ DesugarTestConfiguration::isDesugared,
+ inspector -> {
+ ClassSubject clazz = inspector.clazz(TEST_CLASS);
+ hasInvokesTo(
+ clazz.uniqueMethodWithOriginalName("bar"),
+ // NOTE: The $closeResource helper is _only_ generated by the JDK-9 compiler.
+ "$closeResource",
+ apiLevelHasTwrCloseResourceSupport(true) ? 4 : 0);
+ if (apiLevelHasSuppressedExceptionsSupport(true)) {
+ hasInvokesTo(clazz.mainMethod(), "getSuppressed", 1);
+ } else {
+ inspector.forAllClasses(
+ c ->
+ c.forAllMethods(
+ m -> {
+ hasInvokesTo(m, "getSuppressed", 0);
+ hasInvokesTo(m, "addSuppressed", 0);
+ }));
+ }
+ })
+ .inspectIf(
+ DesugarTestConfiguration::isNotDesugared,
+ inspector -> {
+ ClassSubject clazz = inspector.clazz(TEST_CLASS);
+ // NOTE: The $closeResource helper is _only_ generated by the JDK-9 compiler.
+ hasInvokesTo(clazz.uniqueMethodWithOriginalName("bar"), "$closeResource", 4);
+ hasInvokesTo(clazz.mainMethod(), "getSuppressed", 1);
+ });
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ parameters.assumeR8TestParameters();
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(getProgramInputs())
+ .setMinApi(parameters)
+ .addKeepMainRule(TEST_CLASS)
+ // TODO(b/214250388): Don't warn about AutoClosable in synthesized code.
+ .apply(
+ b -> {
+ if (!apiLevelHasTwrCloseResourceSupport(parameters.isDexRuntime())) {
+ b.addDontWarn(AutoCloseable.class);
+ }
+ })
+ .run(parameters.getRuntime(), TEST_CLASS)
+ .assertSuccessWithOutput(
+ runtimeHasSuppressedExceptionsSupport() ? StringUtils.lines("CLOSE") : "NONE")
+ .inspect(
+ inspector -> {
+ IntBox gets = new IntBox(0);
+ IntBox adds = new IntBox(0);
+ inspector.forAllClasses(
+ c ->
+ c.forAllMethods(
+ m -> {
+ gets.increment(getInvokesTo(m, "getSuppressed").size());
+ adds.increment(getInvokesTo(m, "addSuppressed").size());
+ }));
+ if (apiLevelHasSuppressedExceptionsSupport(parameters.isDexRuntime())) {
+ hasInvokesTo(inspector.clazz(TEST_CLASS).mainMethod(), "getSuppressed", 1);
+ assertEquals(1, gets.get());
+ assertEquals(1, adds.get());
+ } else {
+ assertEquals(0, gets.get());
+ assertEquals(0, adds.get());
+ }
+ });
+ }
+
+ public static void hasInvokesTo(MethodSubject method, String callee, int count) {
+ List<InstructionSubject> getSuppressedCalls = getInvokesTo(method, callee);
+ assertEquals(count, getSuppressedCalls.size());
+ }
+
+ public static List<InstructionSubject> getInvokesTo(MethodSubject method, String callee) {
+ return method
+ .streamInstructions()
+ .filter(i -> i.isInvoke() && i.getMethod().getName().toString().equals(callee))
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/test/examplesJava9/twr/twraddsuppressed/asm/TestClass$MyClosableDump.java b/src/test/examplesJava9/twr/twraddsuppressed/asm/TestClass$MyClosableDump.java
new file mode 100644
index 0000000..039d6c2
--- /dev/null
+++ b/src/test/examplesJava9/twr/twraddsuppressed/asm/TestClass$MyClosableDump.java
@@ -0,0 +1,80 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package twr.twraddsuppressed.asm;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+
+public class TestClass$MyClosableDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter classWriter = new ClassWriter(0);
+ FieldVisitor fieldVisitor;
+ RecordComponentVisitor recordComponentVisitor;
+ MethodVisitor methodVisitor;
+ AnnotationVisitor annotationVisitor0;
+
+ classWriter.visit(
+ V9,
+ ACC_PUBLIC | ACC_SUPER,
+ "twr/twraddsuppressed/TestClass$MyClosable",
+ null,
+ "java/lang/Object",
+ new String[] {"java/io/Closeable"});
+
+ classWriter.visitSource("TestClass.java", null);
+
+ classWriter.visitInnerClass(
+ "twr/twraddsuppressed/TestClass$MyClosable",
+ "twr/twraddsuppressed/TestClass",
+ "MyClosable",
+ ACC_PUBLIC | ACC_STATIC);
+
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(10, label0);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLocalVariable(
+ "this", "Ltwraddsuppressed/TestClass$MyClosable;", null, label0, label1, 0);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "close", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(14, label0);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitLdcInsn("CLOSE");
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitInsn(ATHROW);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLocalVariable(
+ "this", "Ltwraddsuppressed/TestClass$MyClosable;", null, label0, label1, 0);
+ methodVisitor.visitMaxs(3, 1);
+ methodVisitor.visitEnd();
+ }
+ classWriter.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}
diff --git a/src/test/examplesJava9/twr/twraddsuppressed/asm/TestClassDump.java b/src/test/examplesJava9/twr/twraddsuppressed/asm/TestClassDump.java
new file mode 100644
index 0000000..6c26a69
--- /dev/null
+++ b/src/test/examplesJava9/twr/twraddsuppressed/asm/TestClassDump.java
@@ -0,0 +1,398 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Dump of class file for twr.twraddsuppressed.TestClass
+ *
+ * <p>*
+ *
+ * <p>This is used to get the JDK-9 javac code with `$closeResource`, which `-target 9` for later
+ * javac versions does not produce.
+ *
+ * <p>package twr.twraddsuppressed;
+ *
+ * <p>import java.io.Closeable;
+ *
+ * <p>public class TestClass {
+ *
+ * <p>public static class MyClosable implements Closeable { @Override public void close() { throw
+ * new RuntimeException("CLOSE"); } }
+ *
+ * <p>public static void foo() { throw new RuntimeException("FOO"); }
+ *
+ * <p>public static void bar() { // NOTE: The $closeResource helper is _only_ generated by the JDK-9
+ * compiler. // // Use twr twice to have javac generate a shared $closeResource helper. try
+ * (MyClosable closable = new MyClosable()) { foo(); } try (MyClosable closable = new MyClosable())
+ * { foo(); } }
+ *
+ * <p>public static void main(String[] args) { try { bar(); } catch (Exception e) { Throwable[]
+ * suppressed = e.getSuppressed(); if (suppressed.length == 0) { System.out.println("NONE"); } else
+ * { for (Throwable throwable : suppressed) { System.out.println(throwable.getMessage()); } } } } }
+ */
+package twr.twraddsuppressed.asm;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+
+public class TestClassDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter classWriter = new ClassWriter(0);
+ FieldVisitor fieldVisitor;
+ RecordComponentVisitor recordComponentVisitor;
+ MethodVisitor methodVisitor;
+ AnnotationVisitor annotationVisitor0;
+
+ classWriter.visit(
+ V9,
+ ACC_PUBLIC | ACC_SUPER,
+ "twr/twraddsuppressed/TestClass",
+ null,
+ "java/lang/Object",
+ null);
+
+ classWriter.visitSource("TestClass.java", null);
+
+ classWriter.visitInnerClass(
+ "twr/twraddsuppressed/TestClass$MyClosable",
+ "twr/twraddsuppressed/TestClass",
+ "MyClosable",
+ ACC_PUBLIC | ACC_STATIC);
+
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(8, label0);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLocalVariable(
+ "this", "Ltwraddsuppressed/TestClass;", null, label0, label1, 0);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "foo", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(19, label0);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitLdcInsn("FOO");
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitMaxs(3, 0);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "bar", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label3, null);
+ Label label4 = new Label();
+ methodVisitor.visitTryCatchBlock(label2, label4, label3, null);
+ Label label5 = new Label();
+ Label label6 = new Label();
+ Label label7 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label6, label7, "java/lang/Throwable");
+ Label label8 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label6, label8, null);
+ Label label9 = new Label();
+ methodVisitor.visitTryCatchBlock(label7, label9, label8, null);
+ Label label10 = new Label();
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitLineNumber(24, label10);
+ methodVisitor.visitTypeInsn(NEW, "twr/twraddsuppressed/TestClass$MyClosable");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "twr/twraddsuppressed/TestClass$MyClosable", "<init>", "()V", false);
+ methodVisitor.visitVarInsn(ASTORE, 0);
+ Label label11 = new Label();
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(25, label0);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "twr/twraddsuppressed/TestClass", "foo", "()V", false);
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(26, label1);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twraddsuppressed/TestClass",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ Label label12 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label12);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(24, label2);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 2,
+ new Object[] {"twr/twraddsuppressed/TestClass$MyClosable", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(26, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twraddsuppressed/TestClass",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label12);
+ methodVisitor.visitLineNumber(27, label12);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitTypeInsn(NEW, "twr/twraddsuppressed/TestClass$MyClosable");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "twr/twraddsuppressed/TestClass$MyClosable", "<init>", "()V", false);
+ methodVisitor.visitVarInsn(ASTORE, 0);
+ Label label13 = new Label();
+ methodVisitor.visitLabel(label13);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(28, label5);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "twr/twraddsuppressed/TestClass", "foo", "()V", false);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(29, label6);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twraddsuppressed/TestClass",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ Label label14 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label14);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(27, label7);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 2,
+ new Object[] {"twr/twraddsuppressed/TestClass$MyClosable", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(29, label8);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twraddsuppressed/TestClass",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label14);
+ methodVisitor.visitLineNumber(30, label14);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitLocalVariable(
+ "closable", "Ltwraddsuppressed/TestClass$MyClosable;", null, label11, label12, 0);
+ methodVisitor.visitLocalVariable(
+ "closable", "Ltwraddsuppressed/TestClass$MyClosable;", null, label13, label14, 0);
+ methodVisitor.visitMaxs(2, 5);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Exception");
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(34, label0);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "twr/twraddsuppressed/TestClass", "bar", "()V", false);
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(44, label1);
+ Label label3 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label3);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(35, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label4 = new Label();
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(36, label4);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Exception", "getSuppressed", "()[Ljava/lang/Throwable;", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(37, label5);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitInsn(ARRAYLENGTH);
+ Label label6 = new Label();
+ methodVisitor.visitJumpInsn(IFNE, label6);
+ Label label7 = new Label();
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(38, label7);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("NONE");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitJumpInsn(GOTO, label3);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(40, label6);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND,
+ 2,
+ new Object[] {"java/lang/Exception", "[Ljava/lang/Throwable;"},
+ 0,
+ null);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ARRAYLENGTH);
+ methodVisitor.visitVarInsn(ISTORE, 4);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 5);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND,
+ 3,
+ new Object[] {"[Ljava/lang/Throwable;", Opcodes.INTEGER, Opcodes.INTEGER},
+ 0,
+ null);
+ methodVisitor.visitVarInsn(ILOAD, 5);
+ methodVisitor.visitVarInsn(ILOAD, 4);
+ methodVisitor.visitJumpInsn(IF_ICMPGE, label3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ILOAD, 5);
+ methodVisitor.visitInsn(AALOAD);
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(41, label9);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Throwable", "getMessage", "()Ljava/lang/String;", false);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label10 = new Label();
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitLineNumber(40, label10);
+ methodVisitor.visitIincInsn(5, 1);
+ methodVisitor.visitJumpInsn(GOTO, label8);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(45, label3);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL, 1, new Object[] {"[Ljava/lang/String;"}, 0, new Object[] {});
+ methodVisitor.visitInsn(RETURN);
+ Label label11 = new Label();
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitLocalVariable(
+ "throwable", "Ljava/lang/Throwable;", null, label9, label10, 6);
+ methodVisitor.visitLocalVariable(
+ "suppressed", "[Ljava/lang/Throwable;", null, label5, label3, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label4, label3, 1);
+ methodVisitor.visitLocalVariable("args", "[Ljava/lang/String;", null, label0, label11, 0);
+ methodVisitor.visitMaxs(2, 7);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC,
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ null,
+ null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(26, label3);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ Label label4 = new Label();
+ methodVisitor.visitJumpInsn(IFNULL, label4);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label1);
+ Label label5 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false);
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ Label label6 = new Label();
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLocalVariable("x0", "Ljava/lang/Throwable;", null, label3, label6, 0);
+ methodVisitor.visitLocalVariable("x1", "Ljava/lang/AutoCloseable;", null, label3, label6, 1);
+ methodVisitor.visitMaxs(2, 3);
+ methodVisitor.visitEnd();
+ }
+ classWriter.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}
diff --git a/src/test/examplesJava9/twr/twrcloseresource/TwrCloseResourceRunnerTest.java b/src/test/examplesJava9/twr/twrcloseresource/TwrCloseResourceRunnerTest.java
new file mode 100644
index 0000000..1f4f474
--- /dev/null
+++ b/src/test/examplesJava9/twr/twrcloseresource/TwrCloseResourceRunnerTest.java
@@ -0,0 +1,89 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package twr.twrcloseresource;
+
+import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import twr.twrcloseresource.asm.IfaceDump;
+import twr.twrcloseresource.asm.TwrCloseResourceTestDump;
+
+@RunWith(Parameterized.class)
+public class TwrCloseResourceRunnerTest extends TestBase {
+
+ public static Path ANY_REACHABLE_JAR = Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR, "flow.jar");
+
+ private static final String EXPECTED_RESULT =
+ "A\n" + "E\n" + "G\n" + "H\n" + "I\n" + "J\n" + "K\n" + "iA\n" + "iE\n" + "iG\n" + "iH\n"
+ + "iI\n" + "iJ\n" + "iK\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "8\n"
+ + "99\n" + "i1\n" + "i2\n" + "i3\n" + "i4\n" + "i5\n" + "i6\n" + "i7\n" + "i8\n"
+ + "i99\n";
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters()
+ .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+ .withDexRuntimes()
+ .withAllApiLevelsAlsoForCf()
+ .build();
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ testForD8(parameters.getBackend())
+ .addProgramClassFileData(IfaceDump.dump(), TwrCloseResourceTestDump.dump())
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST))
+ .setMinApi(parameters)
+ .run(
+ parameters.getRuntime(),
+ "twr.twrcloseresource.TwrCloseResourceTest",
+ ANY_REACHABLE_JAR.toAbsolutePath().toString())
+ .assertSuccessWithOutput(EXPECTED_RESULT);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ parameters.assumeRuntimeTestParameters();
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(IfaceDump.dump(), TwrCloseResourceTestDump.dump())
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST))
+ .setMinApi(parameters)
+ .setMode(CompilationMode.DEBUG)
+ .applyIf(
+ parameters.isCfRuntime(),
+ t ->
+ t.addOptionsModification(
+ options ->
+ options.getOpenClosedInterfacesOptions().suppressAllOpenInterfaces()))
+ .apply(
+ b ->
+ b.getBuilder()
+ .setDisableTreeShaking(true)
+ .setDisableMinification(true)
+ .addProguardConfiguration(
+ ImmutableList.of("-keepattributes *"), Origin.unknown()))
+ .run(
+ parameters.getRuntime(),
+ "twr.twrcloseresource.TwrCloseResourceTest",
+ ANY_REACHABLE_JAR.toAbsolutePath().toString())
+ .assertSuccessWithOutput(EXPECTED_RESULT);
+ }
+}
diff --git a/src/test/examplesJava9/twr/twrcloseresource/asm/IfaceDump.java b/src/test/examplesJava9/twr/twrcloseresource/asm/IfaceDump.java
new file mode 100644
index 0000000..d049990
--- /dev/null
+++ b/src/test/examplesJava9/twr/twrcloseresource/asm/IfaceDump.java
@@ -0,0 +1,904 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package twr.twrcloseresource.asm;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+
+public class IfaceDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter classWriter = new ClassWriter(0);
+ FieldVisitor fieldVisitor;
+ RecordComponentVisitor recordComponentVisitor;
+ MethodVisitor methodVisitor;
+ AnnotationVisitor annotationVisitor0;
+
+ classWriter.visit(
+ V9,
+ ACC_ABSTRACT | ACC_INTERFACE,
+ "twr/twrcloseresource/Iface",
+ null,
+ "java/lang/Object",
+ null);
+
+ classWriter.visitSource("TwrCloseResourceDuplication$BarDump.java", null);
+
+ {
+ methodVisitor =
+ classWriter.visitMethod(ACC_PUBLIC, "iFoo", "(Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label3, null);
+ Label label4 = new Label();
+ methodVisitor.visitTryCatchBlock(label2, label4, label3, null);
+ Label label5 = new Label();
+ Label label6 = new Label();
+ Label label7 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label6, label7, "java/lang/Exception");
+ Label label8 = new Label();
+ Label label9 = new Label();
+ Label label10 = new Label();
+ methodVisitor.visitTryCatchBlock(label8, label9, label10, "java/lang/Throwable");
+ Label label11 = new Label();
+ methodVisitor.visitTryCatchBlock(label8, label9, label11, null);
+ Label label12 = new Label();
+ methodVisitor.visitTryCatchBlock(label10, label12, label11, null);
+ Label label13 = new Label();
+ Label label14 = new Label();
+ Label label15 = new Label();
+ methodVisitor.visitTryCatchBlock(label13, label14, label15, "java/lang/Throwable");
+ Label label16 = new Label();
+ methodVisitor.visitTryCatchBlock(label13, label14, label16, null);
+ Label label17 = new Label();
+ methodVisitor.visitTryCatchBlock(label15, label17, label16, null);
+ Label label18 = new Label();
+ Label label19 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label18, label19, "java/lang/Exception");
+ Label label20 = new Label();
+ Label label21 = new Label();
+ Label label22 = new Label();
+ methodVisitor.visitTryCatchBlock(label20, label21, label22, "java/lang/Throwable");
+ Label label23 = new Label();
+ methodVisitor.visitTryCatchBlock(label20, label21, label23, null);
+ Label label24 = new Label();
+ methodVisitor.visitTryCatchBlock(label22, label24, label23, null);
+ Label label25 = new Label();
+ Label label26 = new Label();
+ Label label27 = new Label();
+ methodVisitor.visitTryCatchBlock(label25, label26, label27, null);
+ Label label28 = new Label();
+ methodVisitor.visitTryCatchBlock(label27, label28, label27, null);
+ Label label29 = new Label();
+ Label label30 = new Label();
+ methodVisitor.visitTryCatchBlock(label29, label30, label30, "java/lang/Throwable");
+ Label label31 = new Label();
+ Label label32 = new Label();
+ methodVisitor.visitTryCatchBlock(label29, label31, label32, null);
+ Label label33 = new Label();
+ Label label34 = new Label();
+ methodVisitor.visitTryCatchBlock(label33, label34, label34, "java/lang/Exception");
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(82, label5);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label35 = new Label();
+ methodVisitor.visitLabel(label35);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(83, label0);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iA");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(84, label1);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(82, label2);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 4,
+ new Object[] {
+ "twr/twrcloseresource/Iface",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(84, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(91, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ Label label36 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label36);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(84, label7);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label37 = new Label();
+ methodVisitor.visitLabel(label37);
+ methodVisitor.visitLineNumber(85, label37);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iB");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label38 = new Label();
+ methodVisitor.visitLabel(label38);
+ methodVisitor.visitLineNumber(86, label38);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ Label label39 = new Label();
+ methodVisitor.visitLabel(label39);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(87, label8);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iC");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(88, label9);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ Label label40 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label40);
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitLineNumber(86, label10);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 5,
+ new Object[] {
+ "twr/twrcloseresource/Iface",
+ "java/lang/String",
+ "java/lang/Exception",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitLineNumber(88, label11);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ methodVisitor.visitLabel(label12);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label40);
+ methodVisitor.visitLineNumber(89, label40);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iD");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label41 = new Label();
+ methodVisitor.visitLabel(label41);
+ methodVisitor.visitLineNumber(90, label41);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label36);
+ methodVisitor.visitLineNumber(92, label36);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label42 = new Label();
+ methodVisitor.visitLabel(label42);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label13);
+ methodVisitor.visitLineNumber(93, label13);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iE");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label14);
+ methodVisitor.visitLineNumber(94, label14);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitJumpInsn(GOTO, label18);
+ methodVisitor.visitLabel(label15);
+ methodVisitor.visitLineNumber(92, label15);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 4,
+ new Object[] {
+ "twr/twrcloseresource/Iface",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label16);
+ methodVisitor.visitLineNumber(94, label16);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 7);
+ methodVisitor.visitLabel(label17);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 7);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label18);
+ methodVisitor.visitLineNumber(97, label18);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitJumpInsn(GOTO, label33);
+ methodVisitor.visitLabel(label19);
+ methodVisitor.visitLineNumber(95, label19);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label43 = new Label();
+ methodVisitor.visitLabel(label43);
+ methodVisitor.visitLineNumber(96, label43);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iF");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label33);
+ methodVisitor.visitLineNumber(98, label33);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label44 = new Label();
+ methodVisitor.visitLabel(label44);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label29);
+ methodVisitor.visitLineNumber(99, label29);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iG");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label25);
+ methodVisitor.visitLineNumber(100, label25);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ Label label45 = new Label();
+ methodVisitor.visitLabel(label45);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitLabel(label20);
+ methodVisitor.visitLineNumber(101, label20);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iH");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label21);
+ methodVisitor.visitLineNumber(102, label21);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitJumpInsn(GOTO, label26);
+ methodVisitor.visitLabel(label22);
+ methodVisitor.visitLineNumber(100, label22);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 6,
+ new Object[] {
+ "twr/twrcloseresource/Iface",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label23);
+ methodVisitor.visitLineNumber(102, label23);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 8);
+ methodVisitor.visitLabel(label24);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 8);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label26);
+ methodVisitor.visitLineNumber(103, label26);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iI");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label46 = new Label();
+ methodVisitor.visitLabel(label46);
+ methodVisitor.visitLineNumber(104, label46);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label27);
+ methodVisitor.visitLineNumber(103, label27);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 9);
+ methodVisitor.visitLabel(label28);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iI");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label47 = new Label();
+ methodVisitor.visitLabel(label47);
+ methodVisitor.visitLineNumber(104, label47);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label30);
+ methodVisitor.visitLineNumber(98, label30);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label32);
+ methodVisitor.visitLineNumber(106, label32);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 10);
+ methodVisitor.visitLabel(label31);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 10);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label34);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 2,
+ new Object[] {"twr/twrcloseresource/Iface", "java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label48 = new Label();
+ methodVisitor.visitLabel(label48);
+ methodVisitor.visitLineNumber(107, label48);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iJ");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label49 = new Label();
+ methodVisitor.visitLabel(label49);
+ methodVisitor.visitLineNumber(109, label49);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("iK");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label50 = new Label();
+ methodVisitor.visitLabel(label50);
+ methodVisitor.visitLineNumber(110, label50);
+ methodVisitor.visitInsn(RETURN);
+ Label label51 = new Label();
+ methodVisitor.visitLabel(label51);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label35, label6, 2);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label39, label40, 3);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label37, label36, 2);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label42, label18, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label43, label33, 2);
+ methodVisitor.visitLocalVariable("b", "Ljava/util/jar/JarFile;", null, label45, label26, 4);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label44, label34, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label48, label49, 2);
+ methodVisitor.visitLocalVariable(
+ "this", "Ltwrcloseresource/Iface;", null, label5, label51, 0);
+ methodVisitor.visitLocalVariable("arg", "Ljava/lang/String;", null, label5, label51, 1);
+ methodVisitor.visitMaxs(3, 11);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PUBLIC | ACC_STATIC, "iBar", "(Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label1, "java/lang/Throwable");
+ Label label2 = new Label();
+ Label label3 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label2, label3, null);
+ Label label4 = new Label();
+ Label label5 = new Label();
+ methodVisitor.visitTryCatchBlock(label4, label5, label5, "java/lang/Exception");
+ Label label6 = new Label();
+ Label label7 = new Label();
+ methodVisitor.visitTryCatchBlock(label6, label7, label7, "java/lang/Throwable");
+ Label label8 = new Label();
+ Label label9 = new Label();
+ methodVisitor.visitTryCatchBlock(label6, label8, label9, null);
+ Label label10 = new Label();
+ Label label11 = new Label();
+ methodVisitor.visitTryCatchBlock(label10, label11, label11, "java/lang/Exception");
+ Label label12 = new Label();
+ Label label13 = new Label();
+ methodVisitor.visitTryCatchBlock(label12, label13, label13, "java/lang/Throwable");
+ Label label14 = new Label();
+ Label label15 = new Label();
+ methodVisitor.visitTryCatchBlock(label12, label14, label15, null);
+ Label label16 = new Label();
+ Label label17 = new Label();
+ methodVisitor.visitTryCatchBlock(label16, label17, label17, "java/lang/Exception");
+ Label label18 = new Label();
+ Label label19 = new Label();
+ methodVisitor.visitTryCatchBlock(label18, label19, label19, "java/lang/Throwable");
+ Label label20 = new Label();
+ Label label21 = new Label();
+ methodVisitor.visitTryCatchBlock(label18, label20, label21, null);
+ Label label22 = new Label();
+ Label label23 = new Label();
+ methodVisitor.visitTryCatchBlock(label22, label23, label23, "java/lang/Exception");
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(113, label4);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label24 = new Label();
+ methodVisitor.visitLabel(label24);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(114, label0);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label25 = new Label();
+ methodVisitor.visitLabel(label25);
+ methodVisitor.visitLineNumber(115, label25);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(113, label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 3,
+ new Object[] {"java/lang/String", "java/util/jar/JarFile", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(116, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 1,
+ new Object[] {"java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label26 = new Label();
+ methodVisitor.visitLabel(label26);
+ methodVisitor.visitLineNumber(117, label26);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i2");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitLineNumber(119, label10);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label27 = new Label();
+ methodVisitor.visitLabel(label27);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(120, label6);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i3");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label28 = new Label();
+ methodVisitor.visitLabel(label28);
+ methodVisitor.visitLineNumber(121, label28);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(119, label7);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 3,
+ new Object[] {"java/lang/String", "java/util/jar/JarFile", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(122, label9);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 1,
+ new Object[] {"java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label29 = new Label();
+ methodVisitor.visitLabel(label29);
+ methodVisitor.visitLineNumber(123, label29);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i4");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label16);
+ methodVisitor.visitLineNumber(125, label16);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label30 = new Label();
+ methodVisitor.visitLabel(label30);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitLabel(label12);
+ methodVisitor.visitLineNumber(126, label12);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i5");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label31 = new Label();
+ methodVisitor.visitLabel(label31);
+ methodVisitor.visitLineNumber(127, label31);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label13);
+ methodVisitor.visitLineNumber(125, label13);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 3,
+ new Object[] {"java/lang/String", "java/util/jar/JarFile", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label15);
+ methodVisitor.visitLineNumber(128, label15);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ methodVisitor.visitLabel(label14);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label17);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 1,
+ new Object[] {"java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label32 = new Label();
+ methodVisitor.visitLabel(label32);
+ methodVisitor.visitLineNumber(129, label32);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i6");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label22);
+ methodVisitor.visitLineNumber(131, label22);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label33 = new Label();
+ methodVisitor.visitLabel(label33);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitLabel(label18);
+ methodVisitor.visitLineNumber(132, label18);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i7");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label34 = new Label();
+ methodVisitor.visitLabel(label34);
+ methodVisitor.visitLineNumber(133, label34);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label19);
+ methodVisitor.visitLineNumber(131, label19);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 3,
+ new Object[] {"java/lang/String", "java/util/jar/JarFile", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label21);
+ methodVisitor.visitLineNumber(134, label21);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 7);
+ methodVisitor.visitLabel(label20);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/Iface",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ true);
+ methodVisitor.visitVarInsn(ALOAD, 7);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label23);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 1,
+ new Object[] {"java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label35 = new Label();
+ methodVisitor.visitLabel(label35);
+ methodVisitor.visitLineNumber(135, label35);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i8");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label36 = new Label();
+ methodVisitor.visitLabel(label36);
+ methodVisitor.visitLineNumber(137, label36);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("i99");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label37 = new Label();
+ methodVisitor.visitLabel(label37);
+ methodVisitor.visitLineNumber(138, label37);
+ methodVisitor.visitInsn(RETURN);
+ Label label38 = new Label();
+ methodVisitor.visitLabel(label38);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label24, label5, 1);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label26, label10, 1);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label27, label11, 1);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label29, label16, 1);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label30, label17, 1);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label32, label22, 1);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label33, label23, 1);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label35, label36, 1);
+ methodVisitor.visitLocalVariable("arg", "Ljava/lang/String;", null, label4, label38, 0);
+ methodVisitor.visitMaxs(3, 8);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC,
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ null,
+ null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(84, label3);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ Label label4 = new Label();
+ methodVisitor.visitJumpInsn(IFNULL, label4);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label1);
+ Label label5 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false);
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ Label label6 = new Label();
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLocalVariable("x0", "Ljava/lang/Throwable;", null, label3, label6, 0);
+ methodVisitor.visitLocalVariable("x1", "Ljava/lang/AutoCloseable;", null, label3, label6, 1);
+ methodVisitor.visitMaxs(2, 3);
+ methodVisitor.visitEnd();
+ }
+ classWriter.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}
diff --git a/src/test/examplesJava9/twr/twrcloseresource/asm/TwrCloseResourceTestDump.java b/src/test/examplesJava9/twr/twrcloseresource/asm/TwrCloseResourceTestDump.java
new file mode 100644
index 0000000..cdf4cba
--- /dev/null
+++ b/src/test/examplesJava9/twr/twrcloseresource/asm/TwrCloseResourceTestDump.java
@@ -0,0 +1,1042 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Dump of class file for twr.twrcloseresource.TwrCloseResourceTest
+ *
+ * <p>*
+ *
+ * <p>This is used to get the JDK-9 javac code with `$closeResource`, which `-target 9` for later
+ * javac versions does not produce.
+ *
+ * <p>package twr.twrcloseresource;
+ *
+ * <p>import java.util.jar.JarFile;
+ *
+ * <p>public class TwrCloseResourceTest implements Iface { public static void main(String[] args) {
+ * TwrCloseResourceTest o = new TwrCloseResourceTest(); o.foo(args[0]); o.iFoo(args[0]);
+ * bar(args[0]); Iface.iBar(args[0]); }
+ *
+ * <p>synchronized void foo(String arg) { try { try (JarFile a = new JarFile(arg)) {
+ * System.out.println("A"); } catch (Exception e) { System.out.println("B"); try (JarFile a = new
+ * JarFile(arg)) { System.out.println("C"); } System.out.println("D"); throw new RuntimeException();
+ * } try (JarFile a = new JarFile(arg)) { System.out.println("E"); } } catch (Exception e) {
+ * System.out.println("F"); } try (JarFile a = new JarFile(arg)) { System.out.println("G"); try
+ * (JarFile b = new JarFile(arg)) { System.out.println("H"); } finally { System.out.println("I");
+ * throw new RuntimeException(); } } catch (Exception e) { System.out.println("J"); }
+ * System.out.println("K"); }
+ *
+ * <p>static synchronized void bar(String arg) { try (JarFile a = new JarFile(arg)) {
+ * System.out.println("1"); throw new RuntimeException(); } catch (Exception e) {
+ * System.out.println("2"); } try (JarFile a = new JarFile(arg)) { System.out.println("3"); throw
+ * new RuntimeException(); } catch (Exception e) { System.out.println("4"); } try (JarFile a = new
+ * JarFile(arg)) { System.out.println("5"); throw new RuntimeException(); } catch (Exception e) {
+ * System.out.println("6"); } try (JarFile a = new JarFile(arg)) { System.out.println("7"); throw
+ * new RuntimeException(); } catch (Exception e) { System.out.println("8"); }
+ * System.out.println("99"); } }
+ *
+ * <p>interface Iface { default void iFoo(String arg) { try { try (JarFile a = new JarFile(arg)) {
+ * System.out.println("iA"); } catch (Exception e) { System.out.println("iB"); try (JarFile a = new
+ * JarFile(arg)) { System.out.println("iC"); } System.out.println("iD"); throw new
+ * RuntimeException(); } try (JarFile a = new JarFile(arg)) { System.out.println("iE"); } } catch
+ * (Exception e) { System.out.println("iF"); } try (JarFile a = new JarFile(arg)) {
+ * System.out.println("iG"); try (JarFile b = new JarFile(arg)) { System.out.println("iH"); }
+ * finally { System.out.println("iI"); throw new RuntimeException(); } } catch (Exception e) {
+ * System.out.println("iJ"); } System.out.println("iK"); }
+ *
+ * <p>static void iBar(String arg) { try (JarFile a = new JarFile(arg)) { System.out.println("i1");
+ * throw new RuntimeException(); } catch (Exception e) { System.out.println("i2"); } try (JarFile a
+ * = new JarFile(arg)) { System.out.println("i3"); throw new RuntimeException(); } catch (Exception
+ * e) { System.out.println("i4"); } try (JarFile a = new JarFile(arg)) { System.out.println("i5");
+ * throw new RuntimeException(); } catch (Exception e) { System.out.println("i6"); } try (JarFile a
+ * = new JarFile(arg)) { System.out.println("i7"); throw new RuntimeException(); } catch (Exception
+ * e) { System.out.println("i8"); } System.out.println("i99"); } }
+ */
+package twr.twrcloseresource.asm;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+
+public class TwrCloseResourceTestDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter classWriter = new ClassWriter(0);
+ FieldVisitor fieldVisitor;
+ RecordComponentVisitor recordComponentVisitor;
+ MethodVisitor methodVisitor;
+ AnnotationVisitor annotationVisitor0;
+
+ classWriter.visit(
+ V9,
+ ACC_PUBLIC | ACC_SUPER,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ null,
+ "java/lang/Object",
+ new String[] {"twr/twrcloseresource/Iface"});
+
+ classWriter.visitSource("TwrCloseResourceDuplication$BarDump.java", null);
+
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(9, label0);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLocalVariable(
+ "this", "Ltwrcloseresource/TwrCloseResourceTest;", null, label0, label1, 0);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(11, label0);
+ methodVisitor.visitTypeInsn(NEW, "twr/twrcloseresource/TwrCloseResourceTest");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "twr/twrcloseresource/TwrCloseResourceTest", "<init>", "()V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(12, label1);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitInsn(AALOAD);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "foo",
+ "(Ljava/lang/String;)V",
+ false);
+ Label label2 = new Label();
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(13, label2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitInsn(AALOAD);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "iFoo",
+ "(Ljava/lang/String;)V",
+ false);
+ Label label3 = new Label();
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(14, label3);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitInsn(AALOAD);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "bar",
+ "(Ljava/lang/String;)V",
+ false);
+ Label label4 = new Label();
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(15, label4);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitInsn(AALOAD);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "twr/twrcloseresource/Iface", "iBar", "(Ljava/lang/String;)V", true);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(16, label5);
+ methodVisitor.visitInsn(RETURN);
+ Label label6 = new Label();
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLocalVariable("args", "[Ljava/lang/String;", null, label0, label6, 0);
+ methodVisitor.visitLocalVariable(
+ "o", "Ltwrcloseresource/TwrCloseResourceTest;", null, label1, label6, 1);
+ methodVisitor.visitMaxs(3, 2);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(ACC_SYNCHRONIZED, "foo", "(Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label3, null);
+ Label label4 = new Label();
+ methodVisitor.visitTryCatchBlock(label2, label4, label3, null);
+ Label label5 = new Label();
+ Label label6 = new Label();
+ Label label7 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label6, label7, "java/lang/Exception");
+ Label label8 = new Label();
+ Label label9 = new Label();
+ Label label10 = new Label();
+ methodVisitor.visitTryCatchBlock(label8, label9, label10, "java/lang/Throwable");
+ Label label11 = new Label();
+ methodVisitor.visitTryCatchBlock(label8, label9, label11, null);
+ Label label12 = new Label();
+ methodVisitor.visitTryCatchBlock(label10, label12, label11, null);
+ Label label13 = new Label();
+ Label label14 = new Label();
+ Label label15 = new Label();
+ methodVisitor.visitTryCatchBlock(label13, label14, label15, "java/lang/Throwable");
+ Label label16 = new Label();
+ methodVisitor.visitTryCatchBlock(label13, label14, label16, null);
+ Label label17 = new Label();
+ methodVisitor.visitTryCatchBlock(label15, label17, label16, null);
+ Label label18 = new Label();
+ Label label19 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label18, label19, "java/lang/Exception");
+ Label label20 = new Label();
+ Label label21 = new Label();
+ Label label22 = new Label();
+ methodVisitor.visitTryCatchBlock(label20, label21, label22, "java/lang/Throwable");
+ Label label23 = new Label();
+ methodVisitor.visitTryCatchBlock(label20, label21, label23, null);
+ Label label24 = new Label();
+ methodVisitor.visitTryCatchBlock(label22, label24, label23, null);
+ Label label25 = new Label();
+ Label label26 = new Label();
+ Label label27 = new Label();
+ methodVisitor.visitTryCatchBlock(label25, label26, label27, null);
+ Label label28 = new Label();
+ methodVisitor.visitTryCatchBlock(label27, label28, label27, null);
+ Label label29 = new Label();
+ Label label30 = new Label();
+ methodVisitor.visitTryCatchBlock(label29, label30, label30, "java/lang/Throwable");
+ Label label31 = new Label();
+ Label label32 = new Label();
+ methodVisitor.visitTryCatchBlock(label29, label31, label32, null);
+ Label label33 = new Label();
+ Label label34 = new Label();
+ methodVisitor.visitTryCatchBlock(label33, label34, label34, "java/lang/Exception");
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(20, label5);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label35 = new Label();
+ methodVisitor.visitLabel(label35);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(21, label0);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("A");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(22, label1);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(20, label2);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 4,
+ new Object[] {
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(22, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(29, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ Label label36 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label36);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(22, label7);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label37 = new Label();
+ methodVisitor.visitLabel(label37);
+ methodVisitor.visitLineNumber(23, label37);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("B");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label38 = new Label();
+ methodVisitor.visitLabel(label38);
+ methodVisitor.visitLineNumber(24, label38);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ Label label39 = new Label();
+ methodVisitor.visitLabel(label39);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(25, label8);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("C");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(26, label9);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ Label label40 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label40);
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitLineNumber(24, label10);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 5,
+ new Object[] {
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "java/lang/String",
+ "java/lang/Exception",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitLineNumber(26, label11);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ methodVisitor.visitLabel(label12);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label40);
+ methodVisitor.visitLineNumber(27, label40);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("D");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label41 = new Label();
+ methodVisitor.visitLabel(label41);
+ methodVisitor.visitLineNumber(28, label41);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label36);
+ methodVisitor.visitLineNumber(30, label36);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label42 = new Label();
+ methodVisitor.visitLabel(label42);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label13);
+ methodVisitor.visitLineNumber(31, label13);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("E");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label14);
+ methodVisitor.visitLineNumber(32, label14);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitJumpInsn(GOTO, label18);
+ methodVisitor.visitLabel(label15);
+ methodVisitor.visitLineNumber(30, label15);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 4,
+ new Object[] {
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label16);
+ methodVisitor.visitLineNumber(32, label16);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 7);
+ methodVisitor.visitLabel(label17);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 7);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label18);
+ methodVisitor.visitLineNumber(35, label18);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitJumpInsn(GOTO, label33);
+ methodVisitor.visitLabel(label19);
+ methodVisitor.visitLineNumber(33, label19);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label43 = new Label();
+ methodVisitor.visitLabel(label43);
+ methodVisitor.visitLineNumber(34, label43);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("F");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label33);
+ methodVisitor.visitLineNumber(36, label33);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label44 = new Label();
+ methodVisitor.visitLabel(label44);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label29);
+ methodVisitor.visitLineNumber(37, label29);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("G");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label25);
+ methodVisitor.visitLineNumber(38, label25);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ Label label45 = new Label();
+ methodVisitor.visitLabel(label45);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitLabel(label20);
+ methodVisitor.visitLineNumber(39, label20);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("H");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label21);
+ methodVisitor.visitLineNumber(40, label21);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitJumpInsn(GOTO, label26);
+ methodVisitor.visitLabel(label22);
+ methodVisitor.visitLineNumber(38, label22);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 6,
+ new Object[] {
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label23);
+ methodVisitor.visitLineNumber(40, label23);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 8);
+ methodVisitor.visitLabel(label24);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 8);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label26);
+ methodVisitor.visitLineNumber(41, label26);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("I");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label46 = new Label();
+ methodVisitor.visitLabel(label46);
+ methodVisitor.visitLineNumber(42, label46);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label27);
+ methodVisitor.visitLineNumber(41, label27);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 9);
+ methodVisitor.visitLabel(label28);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("I");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label47 = new Label();
+ methodVisitor.visitLabel(label47);
+ methodVisitor.visitLineNumber(42, label47);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label30);
+ methodVisitor.visitLineNumber(36, label30);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label32);
+ methodVisitor.visitLineNumber(44, label32);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 10);
+ methodVisitor.visitLabel(label31);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 10);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label34);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 2,
+ new Object[] {"twr/twrcloseresource/TwrCloseResourceTest", "java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label48 = new Label();
+ methodVisitor.visitLabel(label48);
+ methodVisitor.visitLineNumber(45, label48);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("J");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label49 = new Label();
+ methodVisitor.visitLabel(label49);
+ methodVisitor.visitLineNumber(47, label49);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("K");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label50 = new Label();
+ methodVisitor.visitLabel(label50);
+ methodVisitor.visitLineNumber(48, label50);
+ methodVisitor.visitInsn(RETURN);
+ Label label51 = new Label();
+ methodVisitor.visitLabel(label51);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label35, label6, 2);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label39, label40, 3);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label37, label36, 2);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label42, label18, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label43, label33, 2);
+ methodVisitor.visitLocalVariable("b", "Ljava/util/jar/JarFile;", null, label45, label26, 4);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label44, label34, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label48, label49, 2);
+ methodVisitor.visitLocalVariable(
+ "this", "Ltwrcloseresource/TwrCloseResourceTest;", null, label5, label51, 0);
+ methodVisitor.visitLocalVariable("arg", "Ljava/lang/String;", null, label5, label51, 1);
+ methodVisitor.visitMaxs(3, 11);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_STATIC | ACC_SYNCHRONIZED, "bar", "(Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label1, "java/lang/Throwable");
+ Label label2 = new Label();
+ Label label3 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label2, label3, null);
+ Label label4 = new Label();
+ Label label5 = new Label();
+ methodVisitor.visitTryCatchBlock(label4, label5, label5, "java/lang/Exception");
+ Label label6 = new Label();
+ Label label7 = new Label();
+ methodVisitor.visitTryCatchBlock(label6, label7, label7, "java/lang/Throwable");
+ Label label8 = new Label();
+ Label label9 = new Label();
+ methodVisitor.visitTryCatchBlock(label6, label8, label9, null);
+ Label label10 = new Label();
+ Label label11 = new Label();
+ methodVisitor.visitTryCatchBlock(label10, label11, label11, "java/lang/Exception");
+ Label label12 = new Label();
+ Label label13 = new Label();
+ methodVisitor.visitTryCatchBlock(label12, label13, label13, "java/lang/Throwable");
+ Label label14 = new Label();
+ Label label15 = new Label();
+ methodVisitor.visitTryCatchBlock(label12, label14, label15, null);
+ Label label16 = new Label();
+ Label label17 = new Label();
+ methodVisitor.visitTryCatchBlock(label16, label17, label17, "java/lang/Exception");
+ Label label18 = new Label();
+ Label label19 = new Label();
+ methodVisitor.visitTryCatchBlock(label18, label19, label19, "java/lang/Throwable");
+ Label label20 = new Label();
+ Label label21 = new Label();
+ methodVisitor.visitTryCatchBlock(label18, label20, label21, null);
+ Label label22 = new Label();
+ Label label23 = new Label();
+ methodVisitor.visitTryCatchBlock(label22, label23, label23, "java/lang/Exception");
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(51, label4);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label24 = new Label();
+ methodVisitor.visitLabel(label24);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(52, label0);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label25 = new Label();
+ methodVisitor.visitLabel(label25);
+ methodVisitor.visitLineNumber(53, label25);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(51, label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 3,
+ new Object[] {"java/lang/String", "java/util/jar/JarFile", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(54, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 1,
+ new Object[] {"java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label26 = new Label();
+ methodVisitor.visitLabel(label26);
+ methodVisitor.visitLineNumber(55, label26);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("2");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitLineNumber(57, label10);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label27 = new Label();
+ methodVisitor.visitLabel(label27);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(58, label6);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("3");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label28 = new Label();
+ methodVisitor.visitLabel(label28);
+ methodVisitor.visitLineNumber(59, label28);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(57, label7);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 3,
+ new Object[] {"java/lang/String", "java/util/jar/JarFile", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(60, label9);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 1,
+ new Object[] {"java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label29 = new Label();
+ methodVisitor.visitLabel(label29);
+ methodVisitor.visitLineNumber(61, label29);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("4");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label16);
+ methodVisitor.visitLineNumber(63, label16);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label30 = new Label();
+ methodVisitor.visitLabel(label30);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitLabel(label12);
+ methodVisitor.visitLineNumber(64, label12);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("5");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label31 = new Label();
+ methodVisitor.visitLabel(label31);
+ methodVisitor.visitLineNumber(65, label31);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label13);
+ methodVisitor.visitLineNumber(63, label13);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 3,
+ new Object[] {"java/lang/String", "java/util/jar/JarFile", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label15);
+ methodVisitor.visitLineNumber(66, label15);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ methodVisitor.visitLabel(label14);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label17);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 1,
+ new Object[] {"java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label32 = new Label();
+ methodVisitor.visitLabel(label32);
+ methodVisitor.visitLineNumber(67, label32);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("6");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label22);
+ methodVisitor.visitLineNumber(69, label22);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label33 = new Label();
+ methodVisitor.visitLabel(label33);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitLabel(label18);
+ methodVisitor.visitLineNumber(70, label18);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("7");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label34 = new Label();
+ methodVisitor.visitLabel(label34);
+ methodVisitor.visitLineNumber(71, label34);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label19);
+ methodVisitor.visitLineNumber(69, label19);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 3,
+ new Object[] {"java/lang/String", "java/util/jar/JarFile", "java/lang/Throwable"},
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label21);
+ methodVisitor.visitLineNumber(72, label21);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 7);
+ methodVisitor.visitLabel(label20);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresource/TwrCloseResourceTest",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 7);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label23);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 1,
+ new Object[] {"java/lang/String"},
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 1);
+ Label label35 = new Label();
+ methodVisitor.visitLabel(label35);
+ methodVisitor.visitLineNumber(73, label35);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("8");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label36 = new Label();
+ methodVisitor.visitLabel(label36);
+ methodVisitor.visitLineNumber(75, label36);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("99");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label37 = new Label();
+ methodVisitor.visitLabel(label37);
+ methodVisitor.visitLineNumber(76, label37);
+ methodVisitor.visitInsn(RETURN);
+ Label label38 = new Label();
+ methodVisitor.visitLabel(label38);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label24, label5, 1);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label26, label10, 1);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label27, label11, 1);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label29, label16, 1);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label30, label17, 1);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label32, label22, 1);
+ methodVisitor.visitLocalVariable("a", "Ljava/util/jar/JarFile;", null, label33, label23, 1);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label35, label36, 1);
+ methodVisitor.visitLocalVariable("arg", "Ljava/lang/String;", null, label4, label38, 0);
+ methodVisitor.visitMaxs(3, 8);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC,
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ null,
+ null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(22, label3);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ Label label4 = new Label();
+ methodVisitor.visitJumpInsn(IFNULL, label4);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label1);
+ Label label5 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false);
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ Label label6 = new Label();
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLocalVariable("x0", "Ljava/lang/Throwable;", null, label3, label6, 0);
+ methodVisitor.visitLocalVariable("x1", "Ljava/lang/AutoCloseable;", null, label3, label6, 1);
+ methodVisitor.visitMaxs(2, 3);
+ methodVisitor.visitEnd();
+ }
+ classWriter.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}
diff --git a/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationProfileRewritingTest.java b/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationProfileRewritingTest.java
new file mode 100644
index 0000000..4cad84a
--- /dev/null
+++ b/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationProfileRewritingTest.java
@@ -0,0 +1,245 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package twr.twrcloseresourceduplication;
+
+import static com.android.tools.r8.desugar.LibraryFilesHelper.getJdk11LibraryFiles;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentIf;
+import static com.android.tools.r8.utils.codeinspector.Matchers.notIf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.profile.art.model.ExternalArtProfile;
+import com.android.tools.r8.profile.art.utils.ArtProfileInspector;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.InternalOptions.InlinerOptions;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class TwrCloseResourceDuplicationProfileRewritingTest
+ extends TwrCloseResourceDuplicationTest {
+
+ @Test
+ public void testD8ProfileRewriting() throws Exception {
+ testForD8(parameters.getBackend())
+ .addProgramClassFileData(TwrCloseResourceDuplicationTest.getProgramInputs())
+ .addArtProfileForRewriting(getArtProfile())
+ .addOptionsModification(options -> options.testing.enableSyntheticSharing = false)
+ .applyIf(
+ parameters.isCfRuntime(),
+ testBuilder ->
+ testBuilder
+ .addLibraryFiles(getJdk11LibraryFiles(temp))
+ .addDefaultRuntimeLibrary(parameters),
+ testBuilder ->
+ testBuilder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST)))
+ .noHorizontalClassMergingOfSynthetics()
+ .setMinApi(parameters)
+ .compile()
+ .inspectResidualArtProfile(this::inspectD8)
+ .run(parameters.getRuntime(), MAIN, getZipFile())
+ .assertSuccessWithOutput(TwrCloseResourceDuplicationTest.EXPECTED);
+ }
+
+ @Test
+ public void testR8ProfileRewriting() throws Exception {
+ parameters.assumeR8TestParameters();
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(TwrCloseResourceDuplicationTest.getProgramInputs())
+ .addKeepMainRule(MAIN)
+ .addKeepClassAndMembersRules(FOO, BAR)
+ .addArtProfileForRewriting(getArtProfile())
+ .addOptionsModification(InlinerOptions::disableInlining)
+ .addOptionsModification(options -> options.testing.enableSyntheticSharing = false)
+ .applyIf(
+ parameters.isCfRuntime(),
+ testBuilder ->
+ testBuilder
+ .addLibraryFiles(getJdk11LibraryFiles(temp))
+ .addDefaultRuntimeLibrary(parameters)
+ .addOptionsModification(
+ options ->
+ options.getOpenClosedInterfacesOptions().suppressAllOpenInterfaces()),
+ testBuilder ->
+ testBuilder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST)))
+ .noHorizontalClassMergingOfSynthetics()
+ .setMinApi(parameters)
+ .compile()
+ .inspectResidualArtProfile(this::inspectR8)
+ .run(parameters.getRuntime(), MAIN, getZipFile())
+ .assertSuccessWithOutput(TwrCloseResourceDuplicationTest.EXPECTED);
+ }
+
+ private ExternalArtProfile getArtProfile() {
+ List<TypeReference> closeResourceFormalParameters =
+ ImmutableList.of(
+ Reference.classFromClass(Throwable.class),
+ Reference.classFromClass(AutoCloseable.class));
+ return ExternalArtProfile.builder()
+ .addMethodRule(
+ Reference.method(
+ Reference.classFromTypeName(FOO),
+ "foo",
+ ImmutableList.of(Reference.classFromClass(String.class)),
+ null))
+ .addMethodRule(
+ // NOTE: The $closeResource helper is _only_ generated by the JDK-9 compiler.
+ Reference.method(
+ Reference.classFromTypeName(FOO),
+ "$closeResource",
+ closeResourceFormalParameters,
+ null))
+ .addMethodRule(
+ Reference.method(
+ Reference.classFromTypeName(BAR),
+ "bar",
+ ImmutableList.of(Reference.classFromClass(String.class)),
+ null))
+ .addMethodRule(
+ // NOTE: The $closeResource helper is _only_ generated by the JDK-9 compiler.
+ Reference.method(
+ Reference.classFromTypeName(BAR),
+ "$closeResource",
+ closeResourceFormalParameters,
+ null))
+ .build();
+ }
+
+ private void inspectD8(ArtProfileInspector profileInspector, CodeInspector inspector) {
+ inspect(profileInspector, inspector, hasTwrCloseResourceSupport(true));
+ }
+
+ private void inspectR8(ArtProfileInspector profileInspector, CodeInspector inspector) {
+ inspect(profileInspector, inspector, hasTwrCloseResourceSupport(parameters.isDexRuntime()));
+ }
+
+ private void inspect(
+ ArtProfileInspector profileInspector,
+ CodeInspector inspector,
+ boolean hasTwrCloseResourceSupport) {
+ int expectedClassCount = 3;
+ if (!hasTwrCloseResourceSupport) {
+ expectedClassCount += 8;
+ }
+ if (hasTwrCloseResourceApiOutlines()) {
+ expectedClassCount += 4;
+ }
+ inspector
+ .allClasses()
+ .forEach(c -> System.out.println(c.getDexProgramClass().toSourceString()));
+ assertEquals(expectedClassCount, inspector.allClasses().size());
+ assertThat(inspector.clazz(MAIN), isPresent());
+
+ // Class Foo has two methods foo() and $closeResource().
+ ClassSubject fooClassSubject = inspector.clazz(FOO);
+ assertThat(fooClassSubject, isPresent());
+
+ MethodSubject fooMethodSubject = fooClassSubject.uniqueMethodWithOriginalName("foo");
+ assertThat(fooMethodSubject, isPresent());
+
+ MethodSubject fooCloseResourceMethodSubject =
+ fooClassSubject.uniqueMethodWithOriginalName("$closeResource");
+ assertThat(fooCloseResourceMethodSubject, isPresent());
+
+ // Class Bar has two methods bar() and $closeResource().
+ ClassSubject barClassSubject = inspector.clazz(BAR);
+ assertThat(barClassSubject, isPresent());
+
+ MethodSubject barMethodSubject = barClassSubject.uniqueMethodWithOriginalName("bar");
+ assertThat(barMethodSubject, isPresent());
+
+ MethodSubject barCloseResourceMethodSubject =
+ barClassSubject.uniqueMethodWithOriginalName("$closeResource");
+ assertThat(barCloseResourceMethodSubject, isPresent());
+
+ profileInspector
+ .assertContainsClassRules(fooClassSubject, barClassSubject)
+ .assertContainsMethodRules(
+ fooMethodSubject,
+ fooCloseResourceMethodSubject,
+ barMethodSubject,
+ barCloseResourceMethodSubject);
+
+ // There is 1 backport, 2 synthetic API outlines, and 3 twr classes for both Foo and Bar.
+ for (String clazz : ImmutableList.of(FOO, BAR)) {
+ ClassSubject syntheticApiOutlineClassSubject0 =
+ inspector.clazz(
+ SyntheticItemsTestUtils.syntheticApiOutlineClass(
+ Reference.classFromTypeName(clazz), 0));
+ assertThat(syntheticApiOutlineClassSubject0, isPresentIf(hasTwrCloseResourceApiOutlines()));
+
+ ClassSubject syntheticApiOutlineClassSubject1 =
+ inspector.clazz(
+ SyntheticItemsTestUtils.syntheticApiOutlineClass(
+ Reference.classFromTypeName(clazz), 1));
+ assertThat(syntheticApiOutlineClassSubject1, isPresentIf(hasTwrCloseResourceApiOutlines()));
+
+ int initialSyntheticId = hasTwrCloseResourceApiOutlines() ? 2 : 0;
+
+ ClassSubject syntheticBackportClassSubject =
+ inspector.clazz(
+ SyntheticItemsTestUtils.syntheticBackportClass(
+ Reference.classFromTypeName(clazz), initialSyntheticId));
+ assertThat(syntheticBackportClassSubject, notIf(isPresent(), hasTwrCloseResourceSupport));
+
+ ClassSubject syntheticTwrCloseResourceClassSubject3 =
+ inspector.clazz(
+ SyntheticItemsTestUtils.syntheticTwrCloseResourceClass(
+ Reference.classFromTypeName(clazz), initialSyntheticId + 1));
+ assertThat(
+ syntheticTwrCloseResourceClassSubject3, notIf(isPresent(), hasTwrCloseResourceSupport));
+
+ ClassSubject syntheticTwrCloseResourceClassSubject4 =
+ inspector.clazz(
+ SyntheticItemsTestUtils.syntheticTwrCloseResourceClass(
+ Reference.classFromTypeName(clazz), initialSyntheticId + 2));
+ assertThat(
+ syntheticTwrCloseResourceClassSubject4, notIf(isPresent(), hasTwrCloseResourceSupport));
+
+ ClassSubject syntheticTwrCloseResourceClassSubject5 =
+ inspector.clazz(
+ SyntheticItemsTestUtils.syntheticTwrCloseResourceClass(
+ Reference.classFromTypeName(clazz), initialSyntheticId + 3));
+ assertThat(
+ syntheticTwrCloseResourceClassSubject5, notIf(isPresent(), hasTwrCloseResourceSupport));
+
+ profileInspector.applyIf(
+ hasTwrCloseResourceApiOutlines(),
+ i ->
+ i.assertContainsClassRules(
+ syntheticApiOutlineClassSubject0, syntheticApiOutlineClassSubject1)
+ .assertContainsMethodRules(
+ syntheticApiOutlineClassSubject0.uniqueMethod(),
+ syntheticApiOutlineClassSubject1.uniqueMethod()));
+
+ profileInspector.applyIf(
+ !hasTwrCloseResourceSupport,
+ i ->
+ i.assertContainsClassRules(
+ syntheticBackportClassSubject,
+ syntheticTwrCloseResourceClassSubject3,
+ syntheticTwrCloseResourceClassSubject4,
+ syntheticTwrCloseResourceClassSubject5)
+ .assertContainsMethodRules(
+ syntheticBackportClassSubject.uniqueMethod(),
+ syntheticTwrCloseResourceClassSubject3.uniqueMethod(),
+ syntheticTwrCloseResourceClassSubject4.uniqueMethod(),
+ syntheticTwrCloseResourceClassSubject5.uniqueMethod()));
+ }
+
+ profileInspector.assertContainsNoOtherRules();
+ }
+}
diff --git a/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationTest.java b/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationTest.java
new file mode 100644
index 0000000..930ae37
--- /dev/null
+++ b/src/test/examplesJava9/twr/twrcloseresourceduplication/TwrCloseResourceDuplicationTest.java
@@ -0,0 +1,168 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package twr.twrcloseresourceduplication;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.ZipUtils;
+import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import twr.twrcloseresourceduplication.asm.TwrCloseResourceDuplication$BarDump;
+import twr.twrcloseresourceduplication.asm.TwrCloseResourceDuplication$FooDump;
+import twr.twrcloseresourceduplication.asm.TwrCloseResourceDuplicationDump;
+
+@RunWith(Parameterized.class)
+public class TwrCloseResourceDuplicationTest extends TestBase {
+
+ protected static final String MAIN =
+ "twr.twrcloseresourceduplication.TwrCloseResourceDuplication";
+ protected static final String FOO =
+ "twr.twrcloseresourceduplication.TwrCloseResourceDuplication$Foo";
+ protected static final String BAR =
+ "twr.twrcloseresourceduplication.TwrCloseResourceDuplication$Bar";
+
+ static final int INPUT_CLASSES = 3;
+
+ protected static final String EXPECTED =
+ StringUtils.lines(
+ "foo opened 1",
+ "foo post close 1",
+ "foo opened 2",
+ "foo caught from 2: RuntimeException",
+ "foo post close 2",
+ "bar opened 1",
+ "bar post close 1",
+ "bar opened 2",
+ "bar caught from 2: RuntimeException",
+ "bar post close 2");
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters()
+ .withCfRuntimesStartingFromIncluding(CfVm.JDK9)
+ .withDexRuntimes()
+ .withAllApiLevelsAlsoForCf()
+ .build();
+ }
+
+ protected boolean hasTwrCloseResourceSupport(boolean isDesugaring) {
+ return !isDesugaring
+ || parameters.getApiLevel().isGreaterThanOrEqualTo(apiLevelWithTwrCloseResourceSupport());
+ }
+
+ protected boolean hasTwrCloseResourceApiOutlines() {
+ return parameters.isDexRuntime()
+ && parameters.getApiLevel().isLessThan(apiLevelWithTwrCloseResourceSupport());
+ }
+
+ protected String getZipFile() throws IOException {
+ return ZipUtils.ZipBuilder.builder(temp.newFile("file.zip").toPath())
+ // DEX VMs from 4.4 up-to 9.0 including, will fail if no entry is added.
+ .addBytes("entry", new byte[1])
+ .build()
+ .toString();
+ }
+
+ protected static List<byte[]> getProgramInputs() throws Exception {
+ return ImmutableList.of(
+ TwrCloseResourceDuplicationDump.dump(),
+ TwrCloseResourceDuplication$FooDump.dump(),
+ TwrCloseResourceDuplication$BarDump.dump());
+ }
+
+ @Test
+ public void testJvm() throws Exception {
+ parameters.assumeJvmTestParameters();
+ testForJvm(parameters)
+ .addProgramClassFileData(getProgramInputs())
+ .run(parameters.getRuntime(), MAIN, getZipFile())
+ .assertSuccessWithOutput(EXPECTED);
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ testForD8(parameters.getBackend())
+ .addProgramClassFileData(getProgramInputs())
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST))
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), MAIN, getZipFile())
+ .assertSuccessWithOutput(EXPECTED)
+ .inspect(
+ inspector -> {
+ // NOTE: The $closeResource helper is _only_ generated by the JDK-9 compiler.
+ //
+ // There should be two synthetic classes besides the three program classes.
+ // One for the desugar version of TWR $closeResource and one for the
+ // Throwable.addSuppressed that is still present in the original $closeResource.
+ // TODO(b/214329923): If the original $closeResource is pruned this will decrease.
+ // TODO(b/168568827): Once we support a nested addSuppressed this will increase.
+ int expectedSynthetics = 0;
+ if (!hasTwrCloseResourceSupport(true)) {
+ expectedSynthetics += 2;
+ }
+ if (hasTwrCloseResourceApiOutlines()) {
+ expectedSynthetics += 1;
+ }
+ assertEquals(INPUT_CLASSES + expectedSynthetics, inspector.allClasses().size());
+ });
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ parameters.assumeDexRuntime();
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(getProgramInputs())
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST))
+ .addKeepMainRule(MAIN)
+ .addKeepClassAndMembersRules(FOO, BAR)
+ .setMinApi(parameters)
+ .addDontObfuscate()
+ .run(parameters.getRuntime(), MAIN, getZipFile())
+ .assertSuccessWithOutput(EXPECTED)
+ .inspect(
+ inspector -> {
+ List<FoundClassSubject> foundClassSubjects = inspector.allClasses();
+ Set<String> foundClasses =
+ foundClassSubjects.stream()
+ .map(FoundClassSubject::getFinalName)
+ .collect(Collectors.toSet());
+ // R8 will optimize the generated methods for the two cases below where the thrown
+ // exception is known or not, thus the synthetic methods will be 2.
+ Set<String> nonSyntheticClassOutput = ImmutableSet.of(FOO, BAR, MAIN);
+ if (!hasTwrCloseResourceSupport(parameters.isDexRuntime())) {
+ Set<String> classOutputWithSynthetics = new HashSet<>(nonSyntheticClassOutput);
+ classOutputWithSynthetics.add(
+ SyntheticItemsTestUtils.syntheticApiOutlineClass(
+ Reference.classFromTypeName(BAR), 0)
+ .getTypeName());
+ assertEquals(classOutputWithSynthetics, foundClasses);
+ } else {
+ assertEquals(nonSyntheticClassOutput, foundClasses);
+ }
+ });
+ }
+}
diff --git a/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplication$BarDump.java b/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplication$BarDump.java
new file mode 100644
index 0000000..de20665
--- /dev/null
+++ b/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplication$BarDump.java
@@ -0,0 +1,410 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package twr.twrcloseresourceduplication.asm;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+
+public class TwrCloseResourceDuplication$BarDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter classWriter = new ClassWriter(0);
+ FieldVisitor fieldVisitor;
+ RecordComponentVisitor recordComponentVisitor;
+ MethodVisitor methodVisitor;
+ AnnotationVisitor annotationVisitor0;
+
+ classWriter.visit(
+ V9,
+ ACC_PUBLIC | ACC_SUPER,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ null,
+ "java/lang/Object",
+ null);
+
+ classWriter.visitSource("TwrCloseResourceDuplication.java", null);
+
+ classWriter.visitInnerClass(
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication",
+ "Bar",
+ ACC_PUBLIC | ACC_STATIC);
+
+ classWriter.visitInnerClass(
+ "java/lang/invoke/MethodHandles$Lookup",
+ "java/lang/invoke/MethodHandles",
+ "Lookup",
+ ACC_PUBLIC | ACC_FINAL | ACC_STATIC);
+
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(31, label0);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLocalVariable(
+ "this",
+ "Ltwrcloseresourceduplication/TwrCloseResourceDuplication$Bar;",
+ null,
+ label0,
+ label1,
+ 0);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(0, "bar", "(Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label3, null);
+ Label label4 = new Label();
+ methodVisitor.visitTryCatchBlock(label2, label4, label3, null);
+ Label label5 = new Label();
+ Label label6 = new Label();
+ Label label7 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label6, label7, "java/lang/Exception");
+ Label label8 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label6, label8, null);
+ Label label9 = new Label();
+ methodVisitor.visitTryCatchBlock(label7, label9, label8, null);
+ Label label10 = new Label();
+ methodVisitor.visitTryCatchBlock(label8, label10, label8, null);
+ Label label11 = new Label();
+ Label label12 = new Label();
+ methodVisitor.visitTryCatchBlock(label11, label12, label12, "java/lang/Throwable");
+ Label label13 = new Label();
+ Label label14 = new Label();
+ methodVisitor.visitTryCatchBlock(label11, label13, label14, null);
+ Label label15 = new Label();
+ Label label16 = new Label();
+ methodVisitor.visitTryCatchBlock(label15, label16, label16, "java/lang/Exception");
+ Label label17 = new Label();
+ Label label18 = new Label();
+ methodVisitor.visitTryCatchBlock(label15, label17, label18, null);
+ Label label19 = new Label();
+ methodVisitor.visitTryCatchBlock(label18, label19, label18, null);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(34, label5);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label20 = new Label();
+ methodVisitor.visitLabel(label20);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(35, label0);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("bar opened 1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(36, label1);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(34, label2);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 4,
+ new Object[] {
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(36, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(39, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("bar post close 1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label21 = new Label();
+ methodVisitor.visitLabel(label21);
+ methodVisitor.visitLineNumber(40, label21);
+ methodVisitor.visitJumpInsn(GOTO, label15);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(36, label7);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label22 = new Label();
+ methodVisitor.visitLabel(label22);
+ methodVisitor.visitLineNumber(37, label22);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Class", "getSimpleName", "()Ljava/lang/String;", false);
+ methodVisitor.visitInvokeDynamicInsn(
+ "makeConcatWithConstants",
+ "(Ljava/lang/String;)Ljava/lang/String;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/StringConcatFactory",
+ "makeConcatWithConstants",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {"bar caught from 1: \u0001"});
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(39, label9);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("bar post close 1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label23 = new Label();
+ methodVisitor.visitLabel(label23);
+ methodVisitor.visitLineNumber(40, label23);
+ methodVisitor.visitJumpInsn(GOTO, label15);
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(39, label8);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("bar post close 1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label15);
+ methodVisitor.visitLineNumber(41, label15);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label24 = new Label();
+ methodVisitor.visitLabel(label24);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitLineNumber(42, label11);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("bar opened 2");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label25 = new Label();
+ methodVisitor.visitLabel(label25);
+ methodVisitor.visitLineNumber(43, label25);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label12);
+ methodVisitor.visitLineNumber(41, label12);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 4,
+ new Object[] {
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label14);
+ methodVisitor.visitLineNumber(44, label14);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 7);
+ methodVisitor.visitLabel(label13);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 7);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label16);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 2,
+ new Object[] {
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar", "java/lang/String"
+ },
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label26 = new Label();
+ methodVisitor.visitLabel(label26);
+ methodVisitor.visitLineNumber(45, label26);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Class", "getSimpleName", "()Ljava/lang/String;", false);
+ methodVisitor.visitInvokeDynamicInsn(
+ "makeConcatWithConstants",
+ "(Ljava/lang/String;)Ljava/lang/String;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/StringConcatFactory",
+ "makeConcatWithConstants",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {"bar caught from 2: \u0001"});
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label17);
+ methodVisitor.visitLineNumber(47, label17);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("bar post close 2");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label27 = new Label();
+ methodVisitor.visitLabel(label27);
+ methodVisitor.visitLineNumber(48, label27);
+ Label label28 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label28);
+ methodVisitor.visitLabel(label18);
+ methodVisitor.visitLineNumber(47, label18);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 8);
+ methodVisitor.visitLabel(label19);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("bar post close 2");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ALOAD, 8);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label28);
+ methodVisitor.visitLineNumber(49, label28);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ Label label29 = new Label();
+ methodVisitor.visitLabel(label29);
+ methodVisitor.visitLocalVariable("f", "Ljava/util/jar/JarFile;", null, label20, label6, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label22, label9, 2);
+ methodVisitor.visitLocalVariable("f", "Ljava/util/jar/JarFile;", null, label24, label16, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label26, label17, 2);
+ methodVisitor.visitLocalVariable(
+ "this",
+ "Ltwrcloseresourceduplication/TwrCloseResourceDuplication$Bar;",
+ null,
+ label5,
+ label29,
+ 0);
+ methodVisitor.visitLocalVariable("name", "Ljava/lang/String;", null, label5, label29, 1);
+ methodVisitor.visitMaxs(3, 9);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC,
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ null,
+ null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(36, label3);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ Label label4 = new Label();
+ methodVisitor.visitJumpInsn(IFNULL, label4);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label1);
+ Label label5 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false);
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ Label label6 = new Label();
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLocalVariable("x0", "Ljava/lang/Throwable;", null, label3, label6, 0);
+ methodVisitor.visitLocalVariable("x1", "Ljava/lang/AutoCloseable;", null, label3, label6, 1);
+ methodVisitor.visitMaxs(2, 3);
+ methodVisitor.visitEnd();
+ }
+ classWriter.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}
diff --git a/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplication$FooDump.java b/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplication$FooDump.java
new file mode 100644
index 0000000..68f63a3
--- /dev/null
+++ b/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplication$FooDump.java
@@ -0,0 +1,410 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package twr.twrcloseresourceduplication.asm;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+
+public class TwrCloseResourceDuplication$FooDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter classWriter = new ClassWriter(0);
+ FieldVisitor fieldVisitor;
+ RecordComponentVisitor recordComponentVisitor;
+ MethodVisitor methodVisitor;
+ AnnotationVisitor annotationVisitor0;
+
+ classWriter.visit(
+ V9,
+ ACC_PUBLIC | ACC_SUPER,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ null,
+ "java/lang/Object",
+ null);
+
+ classWriter.visitSource("TwrCloseResourceDuplication.java", null);
+
+ classWriter.visitInnerClass(
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication",
+ "Foo",
+ ACC_PUBLIC | ACC_STATIC);
+
+ classWriter.visitInnerClass(
+ "java/lang/invoke/MethodHandles$Lookup",
+ "java/lang/invoke/MethodHandles",
+ "Lookup",
+ ACC_PUBLIC | ACC_FINAL | ACC_STATIC);
+
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(10, label0);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLocalVariable(
+ "this",
+ "Ltwrcloseresourceduplication/TwrCloseResourceDuplication$Foo;",
+ null,
+ label0,
+ label1,
+ 0);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(0, "foo", "(Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label3, null);
+ Label label4 = new Label();
+ methodVisitor.visitTryCatchBlock(label2, label4, label3, null);
+ Label label5 = new Label();
+ Label label6 = new Label();
+ Label label7 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label6, label7, "java/lang/Exception");
+ Label label8 = new Label();
+ methodVisitor.visitTryCatchBlock(label5, label6, label8, null);
+ Label label9 = new Label();
+ methodVisitor.visitTryCatchBlock(label7, label9, label8, null);
+ Label label10 = new Label();
+ methodVisitor.visitTryCatchBlock(label8, label10, label8, null);
+ Label label11 = new Label();
+ Label label12 = new Label();
+ methodVisitor.visitTryCatchBlock(label11, label12, label12, "java/lang/Throwable");
+ Label label13 = new Label();
+ Label label14 = new Label();
+ methodVisitor.visitTryCatchBlock(label11, label13, label14, null);
+ Label label15 = new Label();
+ Label label16 = new Label();
+ methodVisitor.visitTryCatchBlock(label15, label16, label16, "java/lang/Exception");
+ Label label17 = new Label();
+ Label label18 = new Label();
+ methodVisitor.visitTryCatchBlock(label15, label17, label18, null);
+ Label label19 = new Label();
+ methodVisitor.visitTryCatchBlock(label18, label19, label18, null);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(13, label5);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label20 = new Label();
+ methodVisitor.visitLabel(label20);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(14, label0);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("foo opened 1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(15, label1);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(13, label2);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 4,
+ new Object[] {
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(15, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(18, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("foo post close 1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label21 = new Label();
+ methodVisitor.visitLabel(label21);
+ methodVisitor.visitLineNumber(19, label21);
+ methodVisitor.visitJumpInsn(GOTO, label15);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(15, label7);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label22 = new Label();
+ methodVisitor.visitLabel(label22);
+ methodVisitor.visitLineNumber(16, label22);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Class", "getSimpleName", "()Ljava/lang/String;", false);
+ methodVisitor.visitInvokeDynamicInsn(
+ "makeConcatWithConstants",
+ "(Ljava/lang/String;)Ljava/lang/String;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/StringConcatFactory",
+ "makeConcatWithConstants",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {"foo caught from 1: \u0001"});
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(18, label9);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("foo post close 1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label23 = new Label();
+ methodVisitor.visitLabel(label23);
+ methodVisitor.visitLineNumber(19, label23);
+ methodVisitor.visitJumpInsn(GOTO, label15);
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(18, label8);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 6);
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("foo post close 1");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ALOAD, 6);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label15);
+ methodVisitor.visitLineNumber(20, label15);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitTypeInsn(NEW, "java/util/jar/JarFile");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/util/jar/JarFile", "<init>", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label24 = new Label();
+ methodVisitor.visitLabel(label24);
+ methodVisitor.visitInsn(ACONST_NULL);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitLineNumber(21, label11);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("foo opened 2");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label25 = new Label();
+ methodVisitor.visitLabel(label25);
+ methodVisitor.visitLineNumber(22, label25);
+ methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label12);
+ methodVisitor.visitLineNumber(20, label12);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 4,
+ new Object[] {
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "java/lang/String",
+ "java/util/jar/JarFile",
+ "java/lang/Throwable"
+ },
+ 1,
+ new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 4);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 4);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label14);
+ methodVisitor.visitLineNumber(23, label14);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 7);
+ methodVisitor.visitLabel(label13);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 7);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label16);
+ methodVisitor.visitFrame(
+ Opcodes.F_FULL,
+ 2,
+ new Object[] {
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo", "java/lang/String"
+ },
+ 1,
+ new Object[] {"java/lang/Exception"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ Label label26 = new Label();
+ methodVisitor.visitLabel(label26);
+ methodVisitor.visitLineNumber(24, label26);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Class", "getSimpleName", "()Ljava/lang/String;", false);
+ methodVisitor.visitInvokeDynamicInsn(
+ "makeConcatWithConstants",
+ "(Ljava/lang/String;)Ljava/lang/String;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/StringConcatFactory",
+ "makeConcatWithConstants",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {"foo caught from 2: \u0001"});
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label17);
+ methodVisitor.visitLineNumber(26, label17);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("foo post close 2");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label27 = new Label();
+ methodVisitor.visitLabel(label27);
+ methodVisitor.visitLineNumber(27, label27);
+ Label label28 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label28);
+ methodVisitor.visitLabel(label18);
+ methodVisitor.visitLineNumber(26, label18);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 8);
+ methodVisitor.visitLabel(label19);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("foo post close 2");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitVarInsn(ALOAD, 8);
+ methodVisitor.visitInsn(ATHROW);
+ methodVisitor.visitLabel(label28);
+ methodVisitor.visitLineNumber(28, label28);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ Label label29 = new Label();
+ methodVisitor.visitLabel(label29);
+ methodVisitor.visitLocalVariable("f", "Ljava/util/jar/JarFile;", null, label20, label6, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label22, label9, 2);
+ methodVisitor.visitLocalVariable("f", "Ljava/util/jar/JarFile;", null, label24, label16, 2);
+ methodVisitor.visitLocalVariable("e", "Ljava/lang/Exception;", null, label26, label17, 2);
+ methodVisitor.visitLocalVariable(
+ "this",
+ "Ltwrcloseresourceduplication/TwrCloseResourceDuplication$Foo;",
+ null,
+ label5,
+ label29,
+ 0);
+ methodVisitor.visitLocalVariable("name", "Ljava/lang/String;", null, label5, label29, 1);
+ methodVisitor.visitMaxs(3, 9);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC,
+ "$closeResource",
+ "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V",
+ null,
+ null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
+ Label label3 = new Label();
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(15, label3);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ Label label4 = new Label();
+ methodVisitor.visitJumpInsn(IFNULL, label4);
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label1);
+ Label label5 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
+ methodVisitor.visitVarInsn(ASTORE, 2);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitVarInsn(ALOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/lang/Throwable", "addSuppressed", "(Ljava/lang/Throwable;)V", false);
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ALOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKEINTERFACE, "java/lang/AutoCloseable", "close", "()V", true);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ Label label6 = new Label();
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLocalVariable("x0", "Ljava/lang/Throwable;", null, label3, label6, 0);
+ methodVisitor.visitLocalVariable("x1", "Ljava/lang/AutoCloseable;", null, label3, label6, 1);
+ methodVisitor.visitMaxs(2, 3);
+ methodVisitor.visitEnd();
+ }
+ classWriter.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}
diff --git a/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplicationDump.java b/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplicationDump.java
new file mode 100644
index 0000000..1c05af0
--- /dev/null
+++ b/src/test/examplesJava9/twr/twrcloseresourceduplication/asm/TwrCloseResourceDuplicationDump.java
@@ -0,0 +1,163 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Dump of class file for twr.twrcloseresourceduplication.TwrCloseResourceDuplication
+ *
+ * <p>*
+ *
+ * <p>This is used to get the JDK-9 javac code with `$closeResource`, which `-target 9` for later
+ * javac versions does not produce.
+ *
+ * <p>package twr.twrcloseresourceduplication;
+ *
+ * <p>import java.util.jar.JarFile;
+ *
+ * <p>public class TwrCloseResourceDuplication {
+ *
+ * <p>public static class Foo {
+ *
+ * <p>void foo(String name) { try (JarFile f = new JarFile(name)) { System.out.println("foo opened
+ * 1"); } catch (Exception e) { System.out.println("foo caught from 1: " +
+ * e.getClass().getSimpleName()); } finally { System.out.println("foo post close 1"); } try (JarFile
+ * f = new JarFile(name)) { System.out.println("foo opened 2"); throw new RuntimeException(); }
+ * catch (Exception e) { System.out.println("foo caught from 2: " + e.getClass().getSimpleName()); }
+ * finally { System.out.println("foo post close 2"); } } }
+ *
+ * <p>public static class Bar {
+ *
+ * <p>void bar(String name) { try (JarFile f = new JarFile(name)) { System.out.println("bar opened
+ * 1"); } catch (Exception e) { System.out.println("bar caught from 1: " +
+ * e.getClass().getSimpleName()); } finally { System.out.println("bar post close 1"); } try (JarFile
+ * f = new JarFile(name)) { System.out.println("bar opened 2"); throw new RuntimeException(); }
+ * catch (Exception e) { System.out.println("bar caught from 2: " + e.getClass().getSimpleName()); }
+ * finally { System.out.println("bar post close 2"); } } }
+ *
+ * <p>public static void main(String[] args) { new Foo().foo(args[0]); new Bar().bar(args[0]); } }
+ */
+package twr.twrcloseresourceduplication.asm;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+
+public class TwrCloseResourceDuplicationDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter classWriter = new ClassWriter(0);
+ FieldVisitor fieldVisitor;
+ RecordComponentVisitor recordComponentVisitor;
+ MethodVisitor methodVisitor;
+ AnnotationVisitor annotationVisitor0;
+
+ classWriter.visit(
+ V9,
+ ACC_PUBLIC | ACC_SUPER,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication",
+ null,
+ "java/lang/Object",
+ null);
+
+ classWriter.visitSource("TwrCloseResourceDuplication.java", null);
+
+ classWriter.visitInnerClass(
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication",
+ "Bar",
+ ACC_PUBLIC | ACC_STATIC);
+
+ classWriter.visitInnerClass(
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication",
+ "Foo",
+ ACC_PUBLIC | ACC_STATIC);
+
+ {
+ methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(8, label0);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLocalVariable(
+ "this",
+ "Ltwrcloseresourceduplication/TwrCloseResourceDuplication;",
+ null,
+ label0,
+ label1,
+ 0);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor =
+ classWriter.visitMethod(
+ ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(53, label0);
+ methodVisitor.visitTypeInsn(
+ NEW, "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "<init>",
+ "()V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitInsn(AALOAD);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Foo",
+ "foo",
+ "(Ljava/lang/String;)V",
+ false);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(54, label1);
+ methodVisitor.visitTypeInsn(
+ NEW, "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar");
+ methodVisitor.visitInsn(DUP);
+ methodVisitor.visitMethodInsn(
+ INVOKESPECIAL,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "<init>",
+ "()V",
+ false);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitInsn(AALOAD);
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "twr/twrcloseresourceduplication/TwrCloseResourceDuplication$Bar",
+ "bar",
+ "(Ljava/lang/String;)V",
+ false);
+ Label label2 = new Label();
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(55, label2);
+ methodVisitor.visitInsn(RETURN);
+ Label label3 = new Label();
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLocalVariable("args", "[Ljava/lang/String;", null, label0, label3, 0);
+ methodVisitor.visitMaxs(3, 1);
+ methodVisitor.visitEnd();
+ }
+ classWriter.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}