Test emitting stack-map frames with array types of more than 7 dimensions.
Bug: 111296969
Change-Id: I2f8e9c3a2233670570d7822ad6c2414381459c9e
diff --git a/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTest.java b/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTest.java
new file mode 100644
index 0000000..68277dd
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTest.java
@@ -0,0 +1,41 @@
+// Copyright (c) 2018, 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 com.android.tools.r8.debug;
+
+public class ArrayDimensionGreaterThanSevenTest {
+
+ public static float foo(int x) {
+ try {
+ float[] fs1 = new float[] {42f};
+ float[][] fs2 = new float[][] {fs1};
+ float[][][] fs3 = new float[][][] {fs2};
+ float[][][][] fs4 = new float[][][][] {fs3};
+ float[][][][][] fs5 = new float[][][][][] {fs4};
+ float[][][][][][] fs6 = new float[][][][][][] {fs5};
+ float[][][][][][][] fs7 = new float[][][][][][][] {fs6};
+ float[][][][][][][][] fs8 = new float[][][][][][][][] {fs7};
+ while (x-- > 0) {
+ try {
+ fs8 = x == 0 ? fs8 : null;
+ fs7 = x == 1 ? fs8[1] : fs8[0];
+ fs6 = x == 2 ? fs7[1] : fs7[0];
+ fs5 = x == 3 ? fs6[1] : fs6[0];
+ fs4 = x == 4 ? fs5[1] : fs5[0];
+ fs3 = x == 5 ? fs4[1] : fs4[0];
+ fs2 = x == 6 ? fs3[1] : fs3[0];
+ fs1 = x == 7 ? fs2[1] : fs2[0];
+ } catch (NullPointerException e) {
+ System.out.println("null pointer");
+ }
+ }
+ } catch (RuntimeException e) {
+ return -1f;
+ }
+ return 42;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(foo(args.length + 1));
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTestDump.java b/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTestDump.java
new file mode 100644
index 0000000..5cd652d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTestDump.java
@@ -0,0 +1,590 @@
+package com.android.tools.r8.debug;
+
+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;
+
+public class ArrayDimensionGreaterThanSevenTestDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ FieldVisitor fv;
+ MethodVisitor mv;
+ AnnotationVisitor av0;
+
+ cw.visit(
+ V1_8,
+ ACC_PUBLIC + ACC_SUPER,
+ "com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTest",
+ null,
+ "java/lang/Object",
+ null);
+
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "foo", "(I)F", null, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ Label l1 = new Label();
+ Label l2 = new Label();
+ mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NullPointerException");
+ Label l3 = new Label();
+ Label l4 = new Label();
+ Label l5 = new Label();
+ mv.visitTryCatchBlock(l3, l4, l5, "java/lang/RuntimeException");
+ mv.visitLabel(l3);
+ mv.visitInsn(ICONST_1);
+ mv.visitIntInsn(NEWARRAY, T_FLOAT);
+ mv.visitInsn(DUP);
+ mv.visitInsn(ICONST_0);
+ mv.visitLdcInsn(new Float("42.0"));
+ mv.visitInsn(FASTORE);
+ mv.visitVarInsn(ASTORE, 1);
+ mv.visitInsn(ICONST_1);
+ mv.visitTypeInsn(ANEWARRAY, "[F");
+ mv.visitInsn(DUP);
+ mv.visitInsn(ICONST_0);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitInsn(AASTORE);
+ mv.visitVarInsn(ASTORE, 2);
+ mv.visitInsn(ICONST_1);
+ mv.visitTypeInsn(ANEWARRAY, "[[F");
+ mv.visitInsn(DUP);
+ mv.visitInsn(ICONST_0);
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitInsn(AASTORE);
+ mv.visitVarInsn(ASTORE, 3);
+ mv.visitInsn(ICONST_1);
+ mv.visitTypeInsn(ANEWARRAY, "[[[F");
+ mv.visitInsn(DUP);
+ mv.visitInsn(ICONST_0);
+ mv.visitVarInsn(ALOAD, 3);
+ mv.visitInsn(AASTORE);
+ mv.visitVarInsn(ASTORE, 4);
+ mv.visitInsn(ICONST_1);
+ mv.visitTypeInsn(ANEWARRAY, "[[[[F");
+ mv.visitInsn(DUP);
+ mv.visitInsn(ICONST_0);
+ mv.visitVarInsn(ALOAD, 4);
+ mv.visitInsn(AASTORE);
+ mv.visitVarInsn(ASTORE, 5);
+ mv.visitInsn(ICONST_1);
+ mv.visitTypeInsn(ANEWARRAY, "[[[[[F");
+ mv.visitInsn(DUP);
+ mv.visitInsn(ICONST_0);
+ mv.visitVarInsn(ALOAD, 5);
+ mv.visitInsn(AASTORE);
+ mv.visitVarInsn(ASTORE, 6);
+ mv.visitInsn(ICONST_1);
+ mv.visitTypeInsn(ANEWARRAY, "[[[[[[F");
+ mv.visitInsn(DUP);
+ mv.visitInsn(ICONST_0);
+ mv.visitVarInsn(ALOAD, 6);
+ mv.visitInsn(AASTORE);
+ mv.visitVarInsn(ASTORE, 7);
+ mv.visitInsn(ICONST_1);
+ mv.visitTypeInsn(ANEWARRAY, "[[[[[[[F");
+ mv.visitInsn(DUP);
+ mv.visitInsn(ICONST_0);
+ mv.visitVarInsn(ALOAD, 7);
+ mv.visitInsn(AASTORE);
+ mv.visitVarInsn(ASTORE, 8);
+ Label l6 = new Label();
+ mv.visitLabel(l6);
+ // mv.visitFrame(Opcodes.F_FULL, 9, new Object[] {Opcodes.INTEGER, "[F", "[[F", "[[[F",
+ // "[[[[F", "[[[[[F", "[[[[[[F", "[[[[[[[F", "[[[[[[[[F"}, 0, new Object[] {});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitIincInsn(0, -1);
+ mv.visitJumpInsn(IFLE, l4);
+ mv.visitLabel(l0);
+ mv.visitVarInsn(ILOAD, 0);
+ Label l7 = new Label();
+ mv.visitJumpInsn(IFNE, l7);
+ mv.visitVarInsn(ALOAD, 8);
+ Label l8 = new Label();
+ mv.visitJumpInsn(GOTO, l8);
+ mv.visitLabel(l7);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitInsn(ACONST_NULL);
+ mv.visitTypeInsn(CHECKCAST, "[[[[[[[[F");
+ mv.visitLabel(l8);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"[[[[[[[[F"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"[[[[[[[[F"});
+ mv.visitVarInsn(ASTORE, 8);
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitInsn(ICONST_1);
+ Label l9 = new Label();
+ mv.visitJumpInsn(IF_ICMPNE, l9);
+ mv.visitVarInsn(ALOAD, 8);
+ mv.visitInsn(ICONST_1);
+ mv.visitInsn(AALOAD);
+ Label l10 = new Label();
+ mv.visitJumpInsn(GOTO, l10);
+ mv.visitLabel(l9);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitVarInsn(ALOAD, 8);
+ mv.visitInsn(ICONST_0);
+ mv.visitInsn(AALOAD);
+ mv.visitLabel(l10);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"[[[[[[[F"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"[[[[[[[F"});
+ mv.visitVarInsn(ASTORE, 7);
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitInsn(ICONST_2);
+ Label l11 = new Label();
+ mv.visitJumpInsn(IF_ICMPNE, l11);
+ mv.visitVarInsn(ALOAD, 7);
+ mv.visitInsn(ICONST_1);
+ mv.visitInsn(AALOAD);
+ Label l12 = new Label();
+ mv.visitJumpInsn(GOTO, l12);
+ mv.visitLabel(l11);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitVarInsn(ALOAD, 7);
+ mv.visitInsn(ICONST_0);
+ mv.visitInsn(AALOAD);
+ mv.visitLabel(l12);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"[[[[[[F"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"[[[[[[F"});
+ mv.visitVarInsn(ASTORE, 6);
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitInsn(ICONST_3);
+ Label l13 = new Label();
+ mv.visitJumpInsn(IF_ICMPNE, l13);
+ mv.visitVarInsn(ALOAD, 6);
+ mv.visitInsn(ICONST_1);
+ mv.visitInsn(AALOAD);
+ Label l14 = new Label();
+ mv.visitJumpInsn(GOTO, l14);
+ mv.visitLabel(l13);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitVarInsn(ALOAD, 6);
+ mv.visitInsn(ICONST_0);
+ mv.visitInsn(AALOAD);
+ mv.visitLabel(l14);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"[[[[[F"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"[[[[[F"});
+ mv.visitVarInsn(ASTORE, 5);
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitInsn(ICONST_4);
+ Label l15 = new Label();
+ mv.visitJumpInsn(IF_ICMPNE, l15);
+ mv.visitVarInsn(ALOAD, 5);
+ mv.visitInsn(ICONST_1);
+ mv.visitInsn(AALOAD);
+ Label l16 = new Label();
+ mv.visitJumpInsn(GOTO, l16);
+ mv.visitLabel(l15);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitVarInsn(ALOAD, 5);
+ mv.visitInsn(ICONST_0);
+ mv.visitInsn(AALOAD);
+ mv.visitLabel(l16);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"[[[[F"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"[[[[F"});
+ mv.visitVarInsn(ASTORE, 4);
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitInsn(ICONST_5);
+ Label l17 = new Label();
+ mv.visitJumpInsn(IF_ICMPNE, l17);
+ mv.visitVarInsn(ALOAD, 4);
+ mv.visitInsn(ICONST_1);
+ mv.visitInsn(AALOAD);
+ Label l18 = new Label();
+ mv.visitJumpInsn(GOTO, l18);
+ mv.visitLabel(l17);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitVarInsn(ALOAD, 4);
+ mv.visitInsn(ICONST_0);
+ mv.visitInsn(AALOAD);
+ mv.visitLabel(l18);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"[[[F"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"[[[F"});
+ mv.visitVarInsn(ASTORE, 3);
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitIntInsn(BIPUSH, 6);
+ Label l19 = new Label();
+ mv.visitJumpInsn(IF_ICMPNE, l19);
+ mv.visitVarInsn(ALOAD, 3);
+ mv.visitInsn(ICONST_1);
+ mv.visitInsn(AALOAD);
+ Label l20 = new Label();
+ mv.visitJumpInsn(GOTO, l20);
+ mv.visitLabel(l19);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitVarInsn(ALOAD, 3);
+ mv.visitInsn(ICONST_0);
+ mv.visitInsn(AALOAD);
+ mv.visitLabel(l20);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"[[F"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"[[F"});
+ mv.visitVarInsn(ASTORE, 2);
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitIntInsn(BIPUSH, 7);
+ Label l21 = new Label();
+ mv.visitJumpInsn(IF_ICMPNE, l21);
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitInsn(ICONST_1);
+ mv.visitInsn(AALOAD);
+ Label l22 = new Label();
+ mv.visitJumpInsn(GOTO, l22);
+ mv.visitLabel(l21);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 0,
+ new Object[] {});
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitInsn(ICONST_0);
+ mv.visitInsn(AALOAD);
+ mv.visitLabel(l22);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"[F"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"[F"});
+ mv.visitVarInsn(ASTORE, 1);
+ mv.visitLabel(l1);
+ mv.visitJumpInsn(GOTO, l6);
+ mv.visitLabel(l2);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]
+ // {"java/lang/NullPointerException"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 9,
+ new Object[] {
+ Opcodes.INTEGER,
+ "[F",
+ "[[F",
+ "[[[F",
+ "[[[[F",
+ "[[[[[F",
+ "[[[[[[F",
+ "[[[[[[[F",
+ "[[[[[[[[F"
+ },
+ 1,
+ new Object[] {"java/lang/NullPointerException"});
+ mv.visitVarInsn(ASTORE, 9);
+ mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ mv.visitLdcInsn("null pointer");
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ mv.visitJumpInsn(GOTO, l6);
+ mv.visitLabel(l4);
+ // mv.visitFrame(Opcodes.F_FULL, 1, new Object[] {Opcodes.INTEGER}, 0, new Object[] {});
+ mv.visitFrame(Opcodes.F_NEW, 1, new Object[] {Opcodes.INTEGER}, 0, new Object[] {});
+ Label l23 = new Label();
+ mv.visitJumpInsn(GOTO, l23);
+ mv.visitLabel(l5);
+ // mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/RuntimeException"});
+ mv.visitFrame(
+ Opcodes.F_NEW,
+ 1,
+ new Object[] {Opcodes.INTEGER},
+ 1,
+ new Object[] {"java/lang/RuntimeException"});
+ mv.visitVarInsn(ASTORE, 1);
+ mv.visitLdcInsn(new Float("-1.0"));
+ mv.visitInsn(FRETURN);
+ mv.visitLabel(l23);
+ // mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitFrame(Opcodes.F_NEW, 1, new Object[] {Opcodes.INTEGER}, 0, new Object[] {});
+ mv.visitLdcInsn(new Float("42.0"));
+ mv.visitInsn(FRETURN);
+ mv.visitMaxs(4, 10);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+ mv.visitCode();
+ mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitInsn(ARRAYLENGTH);
+ mv.visitInsn(ICONST_1);
+ mv.visitInsn(IADD);
+ mv.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTest",
+ "foo",
+ "(I)F",
+ false);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(F)V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(3, 1);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTestRunner.java b/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTestRunner.java
new file mode 100644
index 0000000..7866e1b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/debug/ArrayDimensionGreaterThanSevenTestRunner.java
@@ -0,0 +1,82 @@
+// Copyright (c) 2018, 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 com.android.tools.r8.debug;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
+import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.DebuggeeState;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.InternalOptions;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class ArrayDimensionGreaterThanSevenTestRunner extends DebugTestBase {
+
+ private static final Class CLASS = ArrayDimensionGreaterThanSevenTest.class;
+ private static final String NAME = CLASS.getCanonicalName();
+
+ private DebugTestConfig getR8CfConfig(String s, Consumer<InternalOptions> optionsConsumer)
+ throws IOException, com.android.tools.r8.CompilationFailedException {
+ Path cfOut = temp.getRoot().toPath().resolve(s);
+ ToolHelper.runR8(
+ R8Command.builder()
+ .addClassProgramData(ToolHelper.getClassAsBytes(CLASS), Origin.unknown())
+ .setMode(CompilationMode.DEBUG)
+ .setOutput(cfOut, OutputMode.ClassFile)
+ .build(),
+ optionsConsumer);
+ return new CfDebugTestConfig(cfOut);
+ }
+
+ private Stream<DebuggeeState> createStream(DebugTestConfig config) throws Exception {
+ return streamDebugTest(config, NAME, ANDROID_FILTER);
+ }
+
+ @Test
+ @Ignore("b/111296969")
+ // Once R8 does not use expanded frames this can be enabled again.
+ public void test() throws Exception {
+ DebugTestConfig cfConfig = new CfDebugTestConfig().addPaths(ToolHelper.getClassPathForTests());
+ DebugTestConfig d8Config = new D8DebugTestConfig().compileAndAddClasses(temp, CLASS);
+ DebugTestConfig r8JarConfig =
+ getR8CfConfig("r8jar.jar", options -> options.enableCfFrontend = false);
+ DebugTestConfig r8CfConfig =
+ getR8CfConfig("r8cf.jar", options -> options.enableCfFrontend = true);
+ new DebugStreamComparator()
+ .add("CF", createStream(cfConfig))
+ .add("R8/CF", createStream(r8CfConfig))
+ .add("R8/Jar", createStream(r8JarConfig))
+ .add("D8", createStream(d8Config))
+ .compare();
+ }
+
+ @Test
+ // Verify that ASM fails when using expanded frames directly.
+ // See b/111296969
+ public void runTestOnAsmDump() throws Exception {
+ Path out = temp.getRoot().toPath().resolve("out.jar");
+ ArchiveConsumer consumer = new ArchiveConsumer(out);
+ consumer.accept(
+ ArrayDimensionGreaterThanSevenTestDump.dump(),
+ DescriptorUtils.javaTypeToDescriptor(NAME),
+ null);
+ consumer.finished(null);
+ ProcessResult result = ToolHelper.runJava(out, NAME);
+ assertEquals("Expected ASM to fail when using visitFrame(F_NEW, ...)", 1, result.exitCode);
+ assertThat(result.stderr, containsString("java.lang.NoClassDefFoundError: F"));
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/debug/DebugStreamComparator.java b/src/test/java/com/android/tools/r8/debug/DebugStreamComparator.java
index eb85a7c..3a83e30 100644
--- a/src/test/java/com/android/tools/r8/debug/DebugStreamComparator.java
+++ b/src/test/java/com/android/tools/r8/debug/DebugStreamComparator.java
@@ -214,7 +214,8 @@
try {
if (done) {
assertTrue(
- "Not all streams completed at the same time",
+ "Not all streams completed at the same time. "
+ + "Set 'DebugTestBase.DEBUG_TEST = true' to aid in diagnosing the issue.",
states.stream().allMatch(Objects::isNull));
return;
} else {