Desugar MultiANewArray to code that also runs on the JVM
Change-Id: Ibeae5b9662e0ff8ba2867247b4997c84fb6173a4
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
index c135288..0e878ae 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
@@ -38,6 +38,9 @@
}
public CfConstClass(DexType type, boolean ignoreCompatRules) {
+ // Primitive types and void should be retrieved using, for example, java.lang.Integer.TYPE.
+ assert !type.isPrimitiveType();
+ assert !type.isVoidType();
this.type = type;
this.ignoreCompatRules = ignoreCompatRules;
}
@@ -106,22 +109,6 @@
case '[':
case 'L':
return namingLens.lookupInternalName(rewrittenType);
- case 'Z':
- return "java/lang/Boolean/TYPE";
- case 'B':
- return "java/lang/Byte/TYPE";
- case 'S':
- return "java/lang/Short/TYPE";
- case 'C':
- return "java/lang/Character/TYPE";
- case 'I':
- return "java/lang/Integer/TYPE";
- case 'F':
- return "java/lang/Float/TYPE";
- case 'J':
- return "java/lang/Long/TYPE";
- case 'D':
- return "java/lang/Double/TYPE";
default:
throw new Unreachable("Unexpected type in const-class: " + rewrittenType);
}
diff --git a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
index 03dd4d6..c32d6cb 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -68,6 +68,7 @@
import com.android.tools.r8.position.TextRange;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
@@ -994,7 +995,18 @@
visitInsn(Opcodes.IASTORE);
// ..., count1, ..., dim-array
}
- visitLdcInsn(Type.getType(desc.substring(dims)));
+ String baseDesc = desc.substring(dims);
+ if (DescriptorUtils.isPrimitiveDescriptor(baseDesc)) {
+ visitFieldInsn(
+ Opcodes.GETSTATIC,
+ DescriptorUtils.primitiveDescriptorToBoxedInternalName(baseDesc.charAt(0)),
+ "TYPE",
+ "Ljava/lang/Class;");
+ } else if (DescriptorUtils.isVoidDescriptor(baseDesc)) {
+ visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Void", "TYPE", "Ljava/lang/Class;");
+ } else {
+ visitLdcInsn(Type.getType(baseDesc));
+ }
// ..., dim-array, dim-member-type
visitInsn(Opcodes.SWAP);
// ..., dim-member-type, dim-array
diff --git a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
index bfd8334..7cce06b 100644
--- a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
@@ -229,6 +229,14 @@
|| c == 'D';
}
+ public static boolean isVoidDescriptor(String descriptor) {
+ return descriptor.length() == 1 && isVoidType(descriptor.charAt(0));
+ }
+
+ public static boolean isVoidType(char c) {
+ return c == 'V';
+ }
+
public static boolean isArrayDescriptor(String descriptor) {
if (descriptor.length() < 2) {
return false;
@@ -270,6 +278,31 @@
}
}
+ public static String primitiveDescriptorToBoxedInternalName(char primitive) {
+ switch (primitive) {
+ case 'V':
+ return "java/lang/Void";
+ case 'Z':
+ return "java/lang/Boolean";
+ case 'B':
+ return "java/lang/Byte";
+ case 'S':
+ return "java/lang/Short";
+ case 'C':
+ return "java/lang/Character";
+ case 'I':
+ return "java/lang/Integer";
+ case 'J':
+ return "java/lang/Long";
+ case 'F':
+ return "java/lang/Float";
+ case 'D':
+ return "java/lang/Double";
+ default:
+ throw new Unreachable("Unknown type " + primitive);
+ }
+ }
+
/**
* Get unqualified class name from its descriptor.
*
@@ -327,7 +360,7 @@
return Integer.max(classDescriptor.lastIndexOf("/"), 0) + 1;
}
- /**
+ /**
* Get canonical class name from its descriptor.
*
* @param classDescriptor a class descriptor i.e. "La/b/C$D;"
diff --git a/src/test/java/com/android/tools/r8/examples/newarray/NewArrayTestRunner.java b/src/test/java/com/android/tools/r8/examples/newarray/NewArrayTestRunner.java
index 6e4775b..219dbed 100644
--- a/src/test/java/com/android/tools/r8/examples/newarray/NewArrayTestRunner.java
+++ b/src/test/java/com/android/tools/r8/examples/newarray/NewArrayTestRunner.java
@@ -110,9 +110,6 @@
.setMinApi(parameters.getApiLevel())
.setMode(mode)
.run(parameters.getRuntime(), CLASS)
- .applyIf(
- enableMultiANewArrayDesugaringForClassFiles,
- runResult -> runResult.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
- runResult -> runResult.assertSuccessWithOutputLines(EXPECTED));
+ .assertSuccessWithOutputLines(EXPECTED);
}
}