blob: 768375c3726cd840bb84937443f50ca058a735a9 [file] [log] [blame]
Søren Gjessed8547be2024-05-31 08:57:24 +02001// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4package jdk17.ir.optimize.interfaces;
5
6import static org.junit.Assert.assertEquals;
7
8import com.android.tools.r8.TestBase;
9import com.android.tools.r8.TestParameters;
10import com.android.tools.r8.TestParametersCollection;
11import com.android.tools.r8.ToolHelper;
12import com.android.tools.r8.utils.codeinspector.CodeInspector;
13import com.android.tools.r8.utils.codeinspector.InstructionSubject;
14import java.io.Serializable;
15import java.lang.reflect.InvocationTargetException;
16import java.lang.reflect.Method;
17import org.junit.Test;
18import org.junit.runner.RunWith;
19import org.junit.runners.Parameterized;
20import org.junit.runners.Parameterized.Parameter;
21import org.junit.runners.Parameterized.Parameters;
22
23// This test is also present for base test module and JDK-21 to demonstrate the different javac
24// byte code.
25@RunWith(Parameterized.class)
26public class CastWithMultipleBoundsJavacBytecodeTest extends TestBase {
27
28 @Parameter(0)
29 public TestParameters parameters;
30
31 @Parameters(name = "{0}")
32 public static TestParametersCollection data() {
33 return getTestParameters().withAllRuntimesAndApiLevels().build();
34 }
35
36 @Test
37 public void testR8JavacCode() throws Exception {
38 parameters.assumeIsOrSimulateNoneRuntime();
39 // javac from JDK-17 generates the following code for getLambda with three checkcasts to
40 // the two interface types and then to the static return type:
41 //
42 // static java.io.Serializable getLambda();
43 // descriptor: ()Ljava/io/Serializable;
44 // flags: (0x0008) ACC_STATIC
45 // Code:
46 // stack=1, locals=0, args_size=0
47 // 0: invokedynamic #7, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable;
48 // 5: checkcast #11 // class java/io/Serializable
49 // 8: checkcast #13 // class java/lang/Runnable
50 // 11: checkcast #11 // class java/io/Serializable
51 // 14: areturn
52 assertEquals(
53 3,
54 new CodeInspector(ToolHelper.getClassFileForTestClass(TestClass.class))
55 .clazz(TestClass.class)
56 .uniqueMethodWithOriginalName("getLambda")
57 .streamInstructions()
58 .filter(InstructionSubject::isCheckCast)
59 .count());
60 }
61
62 @Test
63 public void testR8() throws Exception {
64 testForR8(parameters.getBackend())
65 .addInnerClassesAndStrippedOuter(getClass())
66 .addKeepMainRule(TestClass.class)
67 .setMinApi(parameters)
68 .addKeepMainRule(TestClass.class)
69 .run(parameters.getRuntime(), TestClass.class);
70 }
71
72 static class TestClass {
73 static void invokeLambda(Object o)
74 throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
75 Method runMethod = o.getClass().getMethod("run");
76 runMethod.invoke(o);
77 }
78
79 static Serializable getLambda() {
80 return (Runnable & Serializable) () -> System.out.println("base lambda");
81 }
82
83 public static void main(String[] args) throws Exception {
84 invokeLambda(getLambda());
85 }
86 }
87}