Support typeSwitch on primitive types
Change-Id: If3931bcbbe5045ee205fae01f8975bae06c80e48
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 02d0092..6fab82f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -897,6 +897,17 @@
return syntheticNaming;
}
+ public final Map<String, DexType> primitiveDescriptorToType =
+ ImmutableMap.of(
+ byteDescriptor.toString(), byteType,
+ charDescriptor.toString(), charType,
+ shortDescriptor.toString(), shortType,
+ intDescriptor.toString(), intType,
+ longDescriptor.toString(), longType,
+ floatDescriptor.toString(), floatType,
+ doubleDescriptor.toString(), doubleType,
+ booleanDescriptor.toString(), booleanType);
+
public final BiMap<DexType, DexType> primitiveToBoxed = HashBiMap.create(
ImmutableMap.<DexType, DexType>builder()
.put(booleanType, boxedBooleanType)
@@ -1898,6 +1909,12 @@
constantBootstrapsType,
createProto(objectType, methodHandlesLookupType, stringType, classType),
"getStaticFinal");
+
+ public final DexMethod primitiveClass =
+ createMethod(
+ constantBootstrapsType,
+ createProto(classType, methodHandlesLookupType, stringType, classType),
+ "primitiveClass");
}
public class BufferMembers {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/LibraryConstantDynamic.java b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/LibraryConstantDynamic.java
index 5c36c18..41873b4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/LibraryConstantDynamic.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/LibraryConstantDynamic.java
@@ -45,6 +45,25 @@
constantDynamic.getBootstrapMethodArguments().get(0), methodHandleMethod);
}
+ public static boolean isPrimitiveClassConstantDynamic(
+ ConstantDynamicReference constantDynamic, DexItemFactory factory) {
+ DexMethod bootstrapMethod = factory.constantBootstrapsMembers.primitiveClass;
+ return constantDynamic.getType().isIdenticalTo(factory.classType)
+ && constantDynamic.getBootstrapMethod().asMethod().isIdenticalTo(bootstrapMethod)
+ && constantDynamic.getBootstrapMethodArguments().size() == 0;
+ }
+
+ public static DexType extractPrimitiveClassConstantDynamic(
+ ConstantDynamicReference constantDynamic, DexItemFactory factory, Definition context) {
+ assert isPrimitiveClassConstantDynamic(constantDynamic, factory);
+ String name = constantDynamic.getName().toString();
+ DexType primitiveType = factory.primitiveDescriptorToType.get(name);
+ if (primitiveType == null) {
+ throw throwInvalidLibraryConstantDynamic("Invalid primitive type" + name, context);
+ }
+ return primitiveType;
+ }
+
public static boolean isBoxedBooleanConstantDynamic(
ConstantDynamicReference constantDynamic, DexItemFactory factory) {
DexMethod bootstrapMethod = factory.constantBootstrapsMembers.getStaticFinal;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/SwitchHelperGenerator.java b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/SwitchHelperGenerator.java
index 7934c56..5bf900b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/SwitchHelperGenerator.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/SwitchHelperGenerator.java
@@ -105,7 +105,7 @@
() -> {
DexItemFactory factory = appView.dexItemFactory();
DexType arg0Type = dexCallSite.methodProto.getParameter(0);
- if (allowsInlinedIntegerEquality(arg0Type, factory)) {
+ if (arg0Type.isPrimitiveType() || allowsInlinedIntegerEquality(arg0Type, factory)) {
return;
}
intEq = generateIntEqMethod(context, eventConsumer, methodProcessingContext);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
index c0b0146..8961590 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
@@ -6,8 +6,10 @@
import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.dispatchEnumDescConstantDynamic;
import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.extractBoxedBooleanConstantDynamic;
+import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.extractPrimitiveClassConstantDynamic;
import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.isBoxedBooleanConstantDynamic;
import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.isEnumDescConstantDynamic;
+import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.isPrimitiveClassConstantDynamic;
import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.isEnumSwitchCallSite;
import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.isTypeSwitchCallSite;
@@ -225,9 +227,14 @@
if (isBoxedBooleanConstantDynamic(constDynamic, factory)) {
booleanConsumer.accept(
extractBoxedBooleanConstantDynamic(constDynamic, factory, context));
- } else {
- assert isEnumDescConstantDynamic(constDynamic, factory);
+ } else if (isEnumDescConstantDynamic(constDynamic, factory)) {
dispatchEnumDescConstantDynamic(constDynamic, factory, context, enumConsumer);
+ } else if (isPrimitiveClassConstantDynamic(constDynamic, factory)) {
+ dexTypeConsumer.accept(
+ extractPrimitiveClassConstantDynamic(constDynamic, factory, context));
+ } else {
+ throw new CompilationError(
+ "Invalid constant dynamic for type switch" + dexValue, context.getOrigin());
}
} else if (dexValue.isDexValueNumber()) {
assert dexValue.isDexValueDouble()
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
index 67e4928..fcea7ca 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.synthetic;
+import com.android.tools.r8.cf.code.CfCmp;
import com.android.tools.r8.cf.code.CfConstNull;
import com.android.tools.r8.cf.code.CfConstNumber;
import com.android.tools.r8.cf.code.CfConstString;
@@ -34,7 +35,9 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueNumber;
+import com.android.tools.r8.ir.code.Cmp.Bias;
import com.android.tools.r8.ir.code.IfType;
+import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.IntBox;
@@ -86,19 +89,16 @@
@Override
public CfCode generateCfCode() {
- // arg 0: Object obj
+ // arg 0: Object|primitive obj
// arg 1: int restart
+ boolean isPrimitiveSwitch = arg0Type.isPrimitiveType();
DexItemFactory factory = appView.dexItemFactory();
List<CfInstruction> instructions = new ArrayList<>();
- CfFrame frame =
- CfFrame.builder()
- .appendLocal(FrameType.initialized(arg0Type))
- .appendLocal(FrameType.intType())
- .build();
+ CfFrame frame = computeCfFrame();
// Objects.checkIndex(restart, length + 1);
- instructions.add(new CfLoad(ValueType.INT, 1));
+ instructions.add(loadArg1());
instructions.add(new CfConstNumber(bootstrapArgs.size() + 1, ValueType.INT));
DexMethod checkIndex =
factory.createMethod(
@@ -108,14 +108,16 @@
instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, checkIndex, false));
instructions.add(new CfStackInstruction(Opcode.Pop));
- // if (obj == null) { return -1; }
- instructions.add(new CfLoad(ValueType.OBJECT, 0));
- CfLabel nonNull = new CfLabel();
- instructions.add(new CfIf(IfType.NE, ValueType.OBJECT, nonNull));
- instructions.add(new CfConstNumber(-1, ValueType.INT));
- instructions.add(new CfReturn(ValueType.INT));
- instructions.add(nonNull);
- instructions.add(frame);
+ if (!isPrimitiveSwitch) {
+ // if (obj == null) { return -1; }
+ instructions.add(loadArg0());
+ CfLabel nonNull = new CfLabel();
+ instructions.add(new CfIf(IfType.NE, ValueType.OBJECT, nonNull));
+ instructions.add(new CfConstNumber(-1, ValueType.INT));
+ instructions.add(new CfReturn(ValueType.INT));
+ instructions.add(nonNull);
+ instructions.add(frame);
+ }
// If no cases, return 0;
if (bootstrapArgs.isEmpty()) {
@@ -130,7 +132,7 @@
cfLabels.add(new CfLabel());
}
cfLabels.add(defaultLabel);
- instructions.add(new CfLoad(ValueType.INT, 1));
+ instructions.add(loadArg1());
instructions.add(new CfSwitch(Kind.TABLE, defaultLabel, new int[] {0}, cfLabels));
IntBox index = new IntBox(0);
@@ -142,18 +144,27 @@
dexType -> {
instructions.add(cfLabels.get(index.get()));
instructions.add(frame);
- instructions.add(new CfLoad(ValueType.OBJECT, 0));
- instructions.add(new CfInstanceOf(dexType));
- instructions.add(
- new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+ if (!isPrimitiveSwitch) {
+ instructions.add(loadArg0());
+ instructions.add(new CfInstanceOf(dexType));
+ instructions.add(
+ new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+ } else {
+ // TODO(b/399808482): Investigate primitive downcast, i.e., an int being
+ // instanceof a byte, short or char.
+ }
instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
instructions.add(new CfReturn(ValueType.INT));
},
intValue -> {
instructions.add(cfLabels.get(index.get()));
instructions.add(frame);
- instructions.add(new CfLoad(ValueType.OBJECT, 0));
- if (allowsInlinedIntegerEquality(arg0Type, factory)) {
+ instructions.add(loadArg0());
+ if (isPrimitiveSwitch) {
+ instructions.add(new CfConstNumber(intValue, ValueType.INT));
+ instructions.add(
+ new CfIfCmp(IfType.NE, ValueType.INT, cfLabels.get(index.get() + 1)));
+ } else if (allowsInlinedIntegerEquality(arg0Type, factory)) {
instructions.add(
new CfInvoke(
Opcodes.INVOKEVIRTUAL,
@@ -167,7 +178,7 @@
assert intEq != null;
instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, intEq, false));
instructions.add(
- new CfIf(IfType.NE, ValueType.INT, cfLabels.get(index.get() + 1)));
+ new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
}
instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
instructions.add(new CfReturn(ValueType.INT));
@@ -175,7 +186,7 @@
dexString -> {
instructions.add(cfLabels.get(index.get()));
instructions.add(frame);
- instructions.add(new CfLoad(ValueType.OBJECT, 0));
+ instructions.add(loadArg0());
instructions.add(new CfConstString(dexString));
instructions.add(
new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
@@ -190,7 +201,7 @@
// TODO(b/399808482): In R8 release, we can analyze at compile-time program enum
// and generate a fast check based on the field. But these information are not
// available in Cf instructions.
- instructions.add(new CfLoad(ValueType.OBJECT, 0));
+ instructions.add(loadArg0());
// TODO(b/399808482): Temporary work-around so we can roll to google3.
DexField field = getEnumField(enumField, type, appView);
if (field == null) {
@@ -229,41 +240,63 @@
bool -> {
instructions.add(cfLabels.get(index.get()));
instructions.add(frame);
- instructions.add(new CfLoad(ValueType.OBJECT, 0));
- instructions.add(new CfConstNumber(BooleanUtils.intValue(bool), ValueType.INT));
- instructions.add(
- new CfInvoke(Opcodes.INVOKESTATIC, factory.booleanMembers.valueOf, false));
- instructions.add(
- new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
- instructions.add(
- new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+ instructions.add(loadArg0());
+ if (isPrimitiveSwitch) {
+ instructions.add(
+ new CfIf(
+ bool ? IfType.EQ : IfType.NE,
+ ValueType.INT,
+ cfLabels.get(index.get() + 1)));
+ } else {
+ instructions.add(new CfConstNumber(BooleanUtils.intValue(bool), ValueType.INT));
+ instructions.add(
+ new CfInvoke(Opcodes.INVOKESTATIC, factory.booleanMembers.valueOf, false));
+ instructions.add(
+ new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
+ instructions.add(
+ new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+ }
instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
instructions.add(new CfReturn(ValueType.INT));
},
dexNumber -> {
instructions.add(cfLabels.get(index.get()));
instructions.add(frame);
- instructions.add(new CfLoad(ValueType.OBJECT, 0));
+ instructions.add(loadArg0());
if (dexNumber.isDexValueFloat()) {
instructions.add(new CfConstNumber(dexNumber.getRawValue(), ValueType.FLOAT));
- instructions.add(
- new CfInvoke(Opcodes.INVOKESTATIC, factory.floatMembers.valueOf, false));
} else if (dexNumber.isDexValueDouble()) {
instructions.add(new CfConstNumber(dexNumber.getRawValue(), ValueType.DOUBLE));
- instructions.add(
- new CfInvoke(Opcodes.INVOKESTATIC, factory.doubleMembers.valueOf, false));
} else if (dexNumber.isDexValueLong()) {
instructions.add(new CfConstNumber(dexNumber.getRawValue(), ValueType.LONG));
- instructions.add(
- new CfInvoke(Opcodes.INVOKESTATIC, factory.longMembers.valueOf, false));
} else {
throw new CompilationError(
"Unexpected dexNumber in type switch desugaring " + dexNumber);
}
- instructions.add(
- new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
- instructions.add(
- new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+ if (isPrimitiveSwitch) {
+ instructions.add(
+ new CfCmp(
+ arg0Type.isLongType() ? Bias.NONE : Bias.GT,
+ NumericType.fromDexType(arg0Type)));
+ instructions.add(
+ new CfIf(IfType.NE, ValueType.INT, cfLabels.get(index.get() + 1)));
+ } else {
+ if (dexNumber.isDexValueFloat()) {
+ instructions.add(
+ new CfInvoke(Opcodes.INVOKESTATIC, factory.floatMembers.valueOf, false));
+ } else if (dexNumber.isDexValueDouble()) {
+ instructions.add(
+ new CfInvoke(Opcodes.INVOKESTATIC, factory.doubleMembers.valueOf, false));
+ } else {
+ assert dexNumber.isDexValueLong();
+ instructions.add(
+ new CfInvoke(Opcodes.INVOKESTATIC, factory.longMembers.valueOf, false));
+ }
+ instructions.add(
+ new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
+ instructions.add(
+ new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+ }
instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
instructions.add(new CfReturn(ValueType.INT));
}));
@@ -292,6 +325,30 @@
return dexEncodedField.getReference();
}
+ private CfLoad loadArg1() {
+ return new CfLoad(ValueType.INT, arg0Type.isWideType() ? 2 : 1);
+ }
+
+ private CfLoad loadArg0() {
+ return new CfLoad(ValueType.fromDexType(arg0Type), 0);
+ }
+
+ private CfFrame computeCfFrame() {
+ DexType frameType =
+ arg0Type.isByteType()
+ || arg0Type.isShortType()
+ || arg0Type.isCharType()
+ || arg0Type.isBooleanType()
+ ? appView.dexItemFactory().intType
+ : arg0Type;
+ CfFrame frame =
+ CfFrame.builder()
+ .appendLocal(FrameType.initialized(frameType))
+ .appendLocal(FrameType.intType())
+ .build();
+ return frame;
+ }
+
public static boolean allowsInlinedIntegerEquality(DexType arg0Type, DexItemFactory factory) {
return arg0Type.isIdenticalTo(factory.boxedByteType)
|| arg0Type.isIdenticalTo(factory.boxedCharType)
diff --git a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMainDump.java b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMainDump.java
new file mode 100644
index 0000000..e85f7fb
--- /dev/null
+++ b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMainDump.java
@@ -0,0 +1,1161 @@
+// Copyright (c) 2025, 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.java23.switchpatternmatching;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ConstantDynamic;
+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;
+import org.objectweb.asm.Type;
+
+/**
+ * This is generated as a dump since the Main class has to be javac compiled withg --enable-preview.
+ *
+ * <p>Dump generated from:
+ *
+ * <pre>
+ * package com.android.tools.r8.java23.switchpatternmatching;
+ *
+ * public class DexIntValuePrimitiveSwitchMain {
+ *
+ * static void booleanSwitch(boolean b) {
+ * switch (b) {
+ * case true -> {
+ * System.out.println("true");
+ * }
+ * default -> {
+ * System.out.println("false");
+ * }
+ * }
+ * }
+ *
+ * static void doubleSwitch(double d) {
+ * switch (d) {
+ * case 42.0 -> {
+ * System.out.println("42");
+ * }
+ * case Double f2 when f2 > 0 -> {
+ * System.out.println("positif");
+ * }
+ * default -> {
+ * System.out.println("negatif");
+ * }
+ * }
+ * }
+ *
+ * static void floatSwitch(float f) {
+ * switch (f) {
+ * case 42.0f -> {
+ * System.out.println("42");
+ * }
+ * case Float f2 when f2 > 0 -> {
+ * System.out.println("positif");
+ * }
+ * default -> {
+ * System.out.println("negatif");
+ * }
+ * }
+ * }
+ *
+ * static void longSwitch(long l) {
+ * switch (l) {
+ * case 42L -> {
+ * System.out.println("42");
+ * }
+ * case Long i2 when i2 > 0 -> {
+ * System.out.println("positif");
+ * }
+ * default -> {
+ * System.out.println("negatif");
+ * }
+ * }
+ * }
+ *
+ * static void intSwitch(int i) {
+ * switch (i) {
+ * case 42 -> {
+ * System.out.println("42");
+ * }
+ * case int i2 when i2 > 0 -> {
+ * System.out.println("positif");
+ * }
+ * default -> {
+ * System.out.println("negatif");
+ * }
+ * }
+ * }
+ *
+ * static void shortSwitch(short s) {
+ * switch (s) {
+ * case 42 -> {
+ * System.out.println("42");
+ * }
+ * case short s2 when s2 > 0 -> {
+ * System.out.println("positif");
+ * }
+ * default -> {
+ * System.out.println("negatif");
+ * }
+ * }
+ * }
+ *
+ * static void charSwitch(char c) {
+ * switch (c) {
+ * case 'c' -> {
+ * System.out.println("c");
+ * }
+ * case char c2 when Character.isUpperCase(c2) -> {
+ * System.out.println("upper");
+ * }
+ * default -> {
+ * System.out.println("lower");
+ * }
+ * }
+ * }
+ *
+ * static void byteSwitch(byte b) {
+ * switch (b) {
+ * case 42 -> {
+ * System.out.println("42");
+ * }
+ * case byte b2 when b2 > 0 -> {
+ * System.out.println("positif");
+ * }
+ * default -> {
+ * System.out.println("negatif");
+ * }
+ * }
+ * }
+ *
+ * public static void main(String[] args) {
+ * intSwitch(42);
+ * intSwitch(12);
+ * intSwitch(-1);
+ *
+ * charSwitch('c');
+ * charSwitch('X');
+ * charSwitch('x');
+ *
+ * byteSwitch((byte) 42);
+ * byteSwitch((byte) 12);
+ * byteSwitch((byte) -1);
+ *
+ * shortSwitch((short) 42);
+ * shortSwitch((short) 12);
+ * shortSwitch((short) -1);
+ *
+ * longSwitch(42L);
+ * longSwitch(12L);
+ * longSwitch(-1L);
+ *
+ * floatSwitch(42.0f);
+ * floatSwitch(12.0f);
+ * floatSwitch(-1.0f);
+ *
+ * doubleSwitch(42.0);
+ * doubleSwitch(12.0);
+ * doubleSwitch(-1.0);
+ *
+ * booleanSwitch(true);
+ * booleanSwitch(false);
+ * }
+ * }
+ * </pre>
+ */
+public class DexIntValuePrimitiveSwitchMainDump implements Opcodes {
+
+ public static byte[] dump() throws Exception {
+
+ ClassWriter classWriter = new ClassWriter(0);
+ FieldVisitor fieldVisitor;
+ RecordComponentVisitor recordComponentVisitor;
+ MethodVisitor methodVisitor;
+ AnnotationVisitor annotationVisitor0;
+
+ classWriter.visit(
+ -65469,
+ ACC_PUBLIC | ACC_SUPER,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ null,
+ "java/lang/Object",
+ null);
+
+ classWriter.visitSource("DexIntValuePrimitiveSwitchMain.java", null);
+
+ 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(7, label0);
+ methodVisitor.visitVarInsn(ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(1, 1);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "booleanSwitch", "(Z)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(10, label0);
+ methodVisitor.visitVarInsn(ILOAD, 0);
+ methodVisitor.visitVarInsn(ISTORE, 1);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 2);
+ methodVisitor.visitInvokeDynamicInsn(
+ "typeSwitch",
+ "(ZI)I",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/runtime/SwitchBootstraps",
+ "typeSwitch",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {
+ new ConstantDynamic(
+ "TRUE",
+ "Ljava/lang/Boolean;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/ConstantBootstraps",
+ "getStaticFinal",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;",
+ false),
+ new Object[] {})
+ });
+ Label label2 = new Label();
+ Label label3 = new Label();
+ methodVisitor.visitLookupSwitchInsn(label3, new int[] {0}, new Label[] {label2});
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(12, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("true");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label4 = new Label();
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(13, label4);
+ Label label5 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label5);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(15, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("false");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(18, label5);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(2, 3);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "doubleSwitch", "(D)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(21, label0);
+ methodVisitor.visitVarInsn(DLOAD, 0);
+ methodVisitor.visitVarInsn(DSTORE, 2);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 4);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND, 2, new Object[] {Opcodes.DOUBLE, Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitVarInsn(DLOAD, 2);
+ methodVisitor.visitVarInsn(ILOAD, 4);
+ methodVisitor.visitInvokeDynamicInsn(
+ "typeSwitch",
+ "(DI)I",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/runtime/SwitchBootstraps",
+ "typeSwitch",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {new Double("42.0"), Type.getType("Ljava/lang/Double;")});
+ Label label2 = new Label();
+ Label label3 = new Label();
+ Label label4 = new Label();
+ methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(23, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("42");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(24, label5);
+ Label label6 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(25, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(DLOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
+ methodVisitor.visitInsn(DCONST_0);
+ methodVisitor.visitInsn(DCMPL);
+ Label label7 = new Label();
+ methodVisitor.visitJumpInsn(IFGT, label7);
+ methodVisitor.visitInsn(ICONST_2);
+ methodVisitor.visitVarInsn(ISTORE, 4);
+ methodVisitor.visitJumpInsn(GOTO, label1);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(26, label7);
+ methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/Double"}, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("positif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(27, label8);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(29, label4);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("negatif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(30, label9);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(32, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(4, 6);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "floatSwitch", "(F)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(35, label0);
+ methodVisitor.visitVarInsn(FLOAD, 0);
+ methodVisitor.visitVarInsn(FSTORE, 1);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND, 2, new Object[] {Opcodes.FLOAT, Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitVarInsn(FLOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 2);
+ methodVisitor.visitInvokeDynamicInsn(
+ "typeSwitch",
+ "(FI)I",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/runtime/SwitchBootstraps",
+ "typeSwitch",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {new Float("42.0"), Type.getType("Ljava/lang/Float;")});
+ Label label2 = new Label();
+ Label label3 = new Label();
+ Label label4 = new Label();
+ methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(37, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("42");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(38, label5);
+ Label label6 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(39, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(FLOAD, 1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
+ methodVisitor.visitVarInsn(ASTORE, 3);
+ methodVisitor.visitVarInsn(ALOAD, 3);
+ methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
+ methodVisitor.visitInsn(FCONST_0);
+ methodVisitor.visitInsn(FCMPL);
+ Label label7 = new Label();
+ methodVisitor.visitJumpInsn(IFGT, label7);
+ methodVisitor.visitInsn(ICONST_2);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ methodVisitor.visitJumpInsn(GOTO, label1);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(40, label7);
+ methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/Float"}, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("positif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(41, label8);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(43, label4);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("negatif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(44, label9);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(46, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(2, 4);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "longSwitch", "(J)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(49, label0);
+ methodVisitor.visitVarInsn(LLOAD, 0);
+ methodVisitor.visitVarInsn(LSTORE, 2);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 4);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND, 2, new Object[] {Opcodes.LONG, Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitVarInsn(LLOAD, 2);
+ methodVisitor.visitVarInsn(ILOAD, 4);
+ methodVisitor.visitInvokeDynamicInsn(
+ "typeSwitch",
+ "(JI)I",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/runtime/SwitchBootstraps",
+ "typeSwitch",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {new Long(42L), Type.getType("Ljava/lang/Long;")});
+ Label label2 = new Label();
+ Label label3 = new Label();
+ Label label4 = new Label();
+ methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(51, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("42");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(52, label5);
+ Label label6 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(53, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(LLOAD, 2);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
+ methodVisitor.visitVarInsn(ASTORE, 5);
+ methodVisitor.visitVarInsn(ALOAD, 5);
+ methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
+ methodVisitor.visitInsn(LCONST_0);
+ methodVisitor.visitInsn(LCMP);
+ Label label7 = new Label();
+ methodVisitor.visitJumpInsn(IFGT, label7);
+ methodVisitor.visitInsn(ICONST_2);
+ methodVisitor.visitVarInsn(ISTORE, 4);
+ methodVisitor.visitJumpInsn(GOTO, label1);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(54, label7);
+ methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/Long"}, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("positif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(55, label8);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(57, label4);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("negatif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(58, label9);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(60, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(4, 6);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "intSwitch", "(I)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(63, label0);
+ methodVisitor.visitVarInsn(ILOAD, 0);
+ methodVisitor.visitVarInsn(ISTORE, 1);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 2);
+ methodVisitor.visitInvokeDynamicInsn(
+ "typeSwitch",
+ "(II)I",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/runtime/SwitchBootstraps",
+ "typeSwitch",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {
+ new Integer(42),
+ new ConstantDynamic(
+ "I",
+ "Ljava/lang/Class;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/ConstantBootstraps",
+ "primitiveClass",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+ false),
+ new Object[] {})
+ });
+ Label label2 = new Label();
+ Label label3 = new Label();
+ Label label4 = new Label();
+ methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(65, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("42");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(66, label5);
+ Label label6 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(67, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ISTORE, 3);
+ methodVisitor.visitVarInsn(ILOAD, 3);
+ Label label7 = new Label();
+ methodVisitor.visitJumpInsn(IFGT, label7);
+ methodVisitor.visitInsn(ICONST_2);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ methodVisitor.visitJumpInsn(GOTO, label1);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(68, label7);
+ methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("positif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(69, label8);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(71, label4);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("negatif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(72, label9);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(74, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(2, 4);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "shortSwitch", "(S)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(77, label0);
+ methodVisitor.visitVarInsn(ILOAD, 0);
+ methodVisitor.visitVarInsn(ISTORE, 1);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 2);
+ methodVisitor.visitInvokeDynamicInsn(
+ "typeSwitch",
+ "(SI)I",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/runtime/SwitchBootstraps",
+ "typeSwitch",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {
+ new Integer(42),
+ new ConstantDynamic(
+ "S",
+ "Ljava/lang/Class;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/ConstantBootstraps",
+ "primitiveClass",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+ false),
+ new Object[] {})
+ });
+ Label label2 = new Label();
+ Label label3 = new Label();
+ Label label4 = new Label();
+ methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(79, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("42");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(80, label5);
+ Label label6 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(81, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ISTORE, 3);
+ methodVisitor.visitVarInsn(ILOAD, 3);
+ Label label7 = new Label();
+ methodVisitor.visitJumpInsn(IFGT, label7);
+ methodVisitor.visitInsn(ICONST_2);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ methodVisitor.visitJumpInsn(GOTO, label1);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(82, label7);
+ methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("positif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(83, label8);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(85, label4);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("negatif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(86, label9);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(88, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(2, 4);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "charSwitch", "(C)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(91, label0);
+ methodVisitor.visitVarInsn(ILOAD, 0);
+ methodVisitor.visitVarInsn(ISTORE, 1);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 2);
+ methodVisitor.visitInvokeDynamicInsn(
+ "typeSwitch",
+ "(CI)I",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/runtime/SwitchBootstraps",
+ "typeSwitch",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {
+ new Integer(99),
+ new ConstantDynamic(
+ "C",
+ "Ljava/lang/Class;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/ConstantBootstraps",
+ "primitiveClass",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+ false),
+ new Object[] {})
+ });
+ Label label2 = new Label();
+ Label label3 = new Label();
+ Label label4 = new Label();
+ methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(93, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ 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);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(94, label5);
+ Label label6 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(95, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ISTORE, 3);
+ methodVisitor.visitVarInsn(ILOAD, 3);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC, "java/lang/Character", "isUpperCase", "(C)Z", false);
+ Label label7 = new Label();
+ methodVisitor.visitJumpInsn(IFNE, label7);
+ methodVisitor.visitInsn(ICONST_2);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ methodVisitor.visitJumpInsn(GOTO, label1);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(96, label7);
+ methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("upper");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(97, label8);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(99, label4);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("lower");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(100, label9);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(102, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(2, 4);
+ methodVisitor.visitEnd();
+ }
+ {
+ methodVisitor = classWriter.visitMethod(ACC_STATIC, "byteSwitch", "(B)V", null, null);
+ methodVisitor.visitCode();
+ Label label0 = new Label();
+ methodVisitor.visitLabel(label0);
+ methodVisitor.visitLineNumber(105, label0);
+ methodVisitor.visitVarInsn(ILOAD, 0);
+ methodVisitor.visitVarInsn(ISTORE, 1);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitFrame(
+ Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ILOAD, 2);
+ methodVisitor.visitInvokeDynamicInsn(
+ "typeSwitch",
+ "(BI)I",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/runtime/SwitchBootstraps",
+ "typeSwitch",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+ false),
+ new Object[] {
+ new Integer(42),
+ new ConstantDynamic(
+ "B",
+ "Ljava/lang/Class;",
+ new Handle(
+ Opcodes.H_INVOKESTATIC,
+ "java/lang/invoke/ConstantBootstraps",
+ "primitiveClass",
+ "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+ false),
+ new Object[] {})
+ });
+ Label label2 = new Label();
+ Label label3 = new Label();
+ Label label4 = new Label();
+ methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(107, label2);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("42");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(108, label5);
+ Label label6 = new Label();
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(109, label3);
+ methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ methodVisitor.visitVarInsn(ILOAD, 1);
+ methodVisitor.visitVarInsn(ISTORE, 3);
+ methodVisitor.visitVarInsn(ILOAD, 3);
+ Label label7 = new Label();
+ methodVisitor.visitJumpInsn(IFGT, label7);
+ methodVisitor.visitInsn(ICONST_2);
+ methodVisitor.visitVarInsn(ISTORE, 2);
+ methodVisitor.visitJumpInsn(GOTO, label1);
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(110, label7);
+ methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("positif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(111, label8);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(113, label4);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+ methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("negatif");
+ methodVisitor.visitMethodInsn(
+ INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(114, label9);
+ methodVisitor.visitJumpInsn(GOTO, label6);
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(116, label6);
+ methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(2, 4);
+ 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(119, label0);
+ methodVisitor.visitIntInsn(BIPUSH, 42);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "intSwitch",
+ "(I)V",
+ false);
+ Label label1 = new Label();
+ methodVisitor.visitLabel(label1);
+ methodVisitor.visitLineNumber(120, label1);
+ methodVisitor.visitIntInsn(BIPUSH, 12);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "intSwitch",
+ "(I)V",
+ false);
+ Label label2 = new Label();
+ methodVisitor.visitLabel(label2);
+ methodVisitor.visitLineNumber(121, label2);
+ methodVisitor.visitInsn(ICONST_M1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "intSwitch",
+ "(I)V",
+ false);
+ Label label3 = new Label();
+ methodVisitor.visitLabel(label3);
+ methodVisitor.visitLineNumber(123, label3);
+ methodVisitor.visitIntInsn(BIPUSH, 99);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "charSwitch",
+ "(C)V",
+ false);
+ Label label4 = new Label();
+ methodVisitor.visitLabel(label4);
+ methodVisitor.visitLineNumber(124, label4);
+ methodVisitor.visitIntInsn(BIPUSH, 88);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "charSwitch",
+ "(C)V",
+ false);
+ Label label5 = new Label();
+ methodVisitor.visitLabel(label5);
+ methodVisitor.visitLineNumber(125, label5);
+ methodVisitor.visitIntInsn(BIPUSH, 120);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "charSwitch",
+ "(C)V",
+ false);
+ Label label6 = new Label();
+ methodVisitor.visitLabel(label6);
+ methodVisitor.visitLineNumber(127, label6);
+ methodVisitor.visitIntInsn(BIPUSH, 42);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "byteSwitch",
+ "(B)V",
+ false);
+ Label label7 = new Label();
+ methodVisitor.visitLabel(label7);
+ methodVisitor.visitLineNumber(128, label7);
+ methodVisitor.visitIntInsn(BIPUSH, 12);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "byteSwitch",
+ "(B)V",
+ false);
+ Label label8 = new Label();
+ methodVisitor.visitLabel(label8);
+ methodVisitor.visitLineNumber(129, label8);
+ methodVisitor.visitInsn(ICONST_M1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "byteSwitch",
+ "(B)V",
+ false);
+ Label label9 = new Label();
+ methodVisitor.visitLabel(label9);
+ methodVisitor.visitLineNumber(131, label9);
+ methodVisitor.visitIntInsn(BIPUSH, 42);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "shortSwitch",
+ "(S)V",
+ false);
+ Label label10 = new Label();
+ methodVisitor.visitLabel(label10);
+ methodVisitor.visitLineNumber(132, label10);
+ methodVisitor.visitIntInsn(BIPUSH, 12);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "shortSwitch",
+ "(S)V",
+ false);
+ Label label11 = new Label();
+ methodVisitor.visitLabel(label11);
+ methodVisitor.visitLineNumber(133, label11);
+ methodVisitor.visitInsn(ICONST_M1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "shortSwitch",
+ "(S)V",
+ false);
+ Label label12 = new Label();
+ methodVisitor.visitLabel(label12);
+ methodVisitor.visitLineNumber(135, label12);
+ methodVisitor.visitLdcInsn(new Long(42L));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "longSwitch",
+ "(J)V",
+ false);
+ Label label13 = new Label();
+ methodVisitor.visitLabel(label13);
+ methodVisitor.visitLineNumber(136, label13);
+ methodVisitor.visitLdcInsn(new Long(12L));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "longSwitch",
+ "(J)V",
+ false);
+ Label label14 = new Label();
+ methodVisitor.visitLabel(label14);
+ methodVisitor.visitLineNumber(137, label14);
+ methodVisitor.visitLdcInsn(new Long(-1L));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "longSwitch",
+ "(J)V",
+ false);
+ Label label15 = new Label();
+ methodVisitor.visitLabel(label15);
+ methodVisitor.visitLineNumber(139, label15);
+ methodVisitor.visitLdcInsn(new Float("42.0"));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "floatSwitch",
+ "(F)V",
+ false);
+ Label label16 = new Label();
+ methodVisitor.visitLabel(label16);
+ methodVisitor.visitLineNumber(140, label16);
+ methodVisitor.visitLdcInsn(new Float("12.0"));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "floatSwitch",
+ "(F)V",
+ false);
+ Label label17 = new Label();
+ methodVisitor.visitLabel(label17);
+ methodVisitor.visitLineNumber(141, label17);
+ methodVisitor.visitLdcInsn(new Float("-1.0"));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "floatSwitch",
+ "(F)V",
+ false);
+ Label label18 = new Label();
+ methodVisitor.visitLabel(label18);
+ methodVisitor.visitLineNumber(143, label18);
+ methodVisitor.visitLdcInsn(new Double("42.0"));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "doubleSwitch",
+ "(D)V",
+ false);
+ Label label19 = new Label();
+ methodVisitor.visitLabel(label19);
+ methodVisitor.visitLineNumber(144, label19);
+ methodVisitor.visitLdcInsn(new Double("12.0"));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "doubleSwitch",
+ "(D)V",
+ false);
+ Label label20 = new Label();
+ methodVisitor.visitLabel(label20);
+ methodVisitor.visitLineNumber(145, label20);
+ methodVisitor.visitLdcInsn(new Double("-1.0"));
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "doubleSwitch",
+ "(D)V",
+ false);
+ Label label21 = new Label();
+ methodVisitor.visitLabel(label21);
+ methodVisitor.visitLineNumber(147, label21);
+ methodVisitor.visitInsn(ICONST_1);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "booleanSwitch",
+ "(Z)V",
+ false);
+ Label label22 = new Label();
+ methodVisitor.visitLabel(label22);
+ methodVisitor.visitLineNumber(148, label22);
+ methodVisitor.visitInsn(ICONST_0);
+ methodVisitor.visitMethodInsn(
+ INVOKESTATIC,
+ "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+ "booleanSwitch",
+ "(Z)V",
+ false);
+ Label label23 = new Label();
+ methodVisitor.visitLabel(label23);
+ methodVisitor.visitLineNumber(149, label23);
+ methodVisitor.visitInsn(RETURN);
+ methodVisitor.visitMaxs(2, 1);
+ methodVisitor.visitEnd();
+ }
+ classWriter.visitEnd();
+
+ return classWriter.toByteArray();
+ }
+}
diff --git a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchTest.java b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchTest.java
new file mode 100644
index 0000000..9636183
--- /dev/null
+++ b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchTest.java
@@ -0,0 +1,76 @@
+// Copyright (c) 2025, 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.java23.switchpatternmatching;
+
+import com.android.tools.r8.JdkClassFileProvider;
+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.utils.StringUtils;
+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;
+
+@RunWith(Parameterized.class)
+public class DexIntValuePrimitiveSwitchTest extends TestBase {
+
+ private static final String MAIN =
+ "com.android.tools.r8.java23.switchpatternmatching.DexIntValuePrimitiveSwitchMain";
+
+ @Parameter public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters()
+ .withCfRuntimesStartingFromIncluding(CfVm.JDK23)
+ .withDexRuntimes()
+ .withAllApiLevelsAlsoForCf()
+ .build();
+ }
+
+ public static String EXPECTED_OUTPUT =
+ StringUtils.lines(
+ "42", "positif", "negatif", "c", "upper", "lower", "42", "positif", "negatif", "42",
+ "positif", "negatif", "42", "positif", "negatif", "42", "positif", "negatif", "42",
+ "positif", "negatif", "true", "false");
+
+ @Test
+ public void testJvm() throws Exception {
+ parameters.assumeJvmTestParameters();
+ testForJvm(parameters)
+ .enablePreview()
+ .addProgramClassFileData(DexIntValuePrimitiveSwitchMainDump.dump())
+ .run(parameters.getRuntime(), MAIN)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ testForD8(parameters.getBackend())
+ .addProgramClassFileData(DexIntValuePrimitiveSwitchMainDump.dump())
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), MAIN)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ parameters.assumeR8TestParameters();
+ testForR8(parameters.getBackend())
+ .addProgramClassFileData(DexIntValuePrimitiveSwitchMainDump.dump())
+ .applyIf(
+ parameters.isCfRuntime(),
+ b -> b.addLibraryProvider(JdkClassFileProvider.fromSystemJdk()))
+ .setMinApi(parameters)
+ .addKeepMainRule(MAIN)
+ .compile()
+ .applyIf(parameters.isCfRuntime(), b -> b.addVmArguments("--enable-preview"))
+ .run(parameters.getRuntime(), MAIN)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ }
+}
diff --git a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValueSwitchTest.java b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValueSwitchTest.java
new file mode 100644
index 0000000..3fe7fbb
--- /dev/null
+++ b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValueSwitchTest.java
@@ -0,0 +1,173 @@
+// Copyright (c) 2025, 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.java23.switchpatternmatching;
+
+import static com.android.tools.r8.desugar.switchpatternmatching.SwitchTestHelper.hasJdk21TypeSwitch;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.JdkClassFileProvider;
+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.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+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;
+
+@RunWith(Parameterized.class)
+public class DexIntValueSwitchTest extends TestBase {
+
+ @Parameter public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters()
+ .withCfRuntimesStartingFromIncluding(CfVm.JDK23)
+ .withDexRuntimes()
+ .withAllApiLevelsAlsoForCf()
+ .build();
+ }
+
+ public static String EXPECTED_OUTPUT =
+ StringUtils.lines(
+ "null", "42", "positif", "negatif", "null", "c", "upper", "lower", "null", "42",
+ "positif", "negatif", "null", "42", "positif", "negatif");
+
+ @Test
+ public void testJvm() throws Exception {
+ assumeTrue(parameters.isCfRuntime());
+ CodeInspector inspector = new CodeInspector(ToolHelper.getClassFileForTestClass(Main.class));
+ assertTrue(
+ hasJdk21TypeSwitch(inspector.clazz(Main.class).uniqueMethodWithOriginalName("intSwitch")));
+
+ parameters.assumeJvmTestParameters();
+ testForJvm(parameters)
+ .addInnerClassesAndStrippedOuter(getClass())
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ testForD8(parameters.getBackend())
+ .addInnerClassesAndStrippedOuter(getClass())
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ parameters.assumeR8TestParameters();
+ testForR8(parameters.getBackend())
+ .addInnerClassesAndStrippedOuter(getClass())
+ .applyIf(
+ parameters.isCfRuntime(),
+ b -> b.addLibraryProvider(JdkClassFileProvider.fromSystemJdk()))
+ .setMinApi(parameters)
+ .addKeepMainRule(Main.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ }
+
+ static class Main {
+
+ static void intSwitch(Integer i) {
+ switch (i) {
+ case null -> {
+ System.out.println("null");
+ }
+ case 42 -> {
+ System.out.println("42");
+ }
+ case Integer i2 when i2 > 0 -> {
+ System.out.println("positif");
+ }
+ default -> {
+ System.out.println("negatif");
+ }
+ }
+ }
+
+ static void shortSwitch(Short s) {
+ switch (s) {
+ case null -> {
+ System.out.println("null");
+ }
+ case 42 -> {
+ System.out.println("42");
+ }
+ case Short s2 when s2 > 0 -> {
+ System.out.println("positif");
+ }
+ default -> {
+ System.out.println("negatif");
+ }
+ }
+ }
+
+ static void charSwitch(Character c) {
+ switch (c) {
+ case null -> {
+ System.out.println("null");
+ }
+ case 'c' -> {
+ System.out.println("c");
+ }
+ case Character c2 when Character.isUpperCase(c2) -> {
+ System.out.println("upper");
+ }
+ default -> {
+ System.out.println("lower");
+ }
+ }
+ }
+
+ static void byteSwitch(Byte b) {
+ switch (b) {
+ case null -> {
+ System.out.println("null");
+ }
+ case 42 -> {
+ System.out.println("42");
+ }
+ case Byte b2 when b2 > 0 -> {
+ System.out.println("positif");
+ }
+ default -> {
+ System.out.println("negatif");
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ intSwitch(null);
+ intSwitch(42);
+ intSwitch(12);
+ intSwitch(-1);
+
+ charSwitch(null);
+ charSwitch('c');
+ charSwitch('X');
+ charSwitch('x');
+
+ byteSwitch(null);
+ byteSwitch((byte) 42);
+ byteSwitch((byte) 12);
+ byteSwitch((byte) -1);
+
+ shortSwitch(null);
+ shortSwitch((short) 42);
+ shortSwitch((short) 12);
+ shortSwitch((short) -1);
+ }
+ }
+}