1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import annotations.BootstrapMethod;
18 import annotations.CalledByIndy;
19 import annotations.Constant;
20 import java.lang.invoke.CallSite;
21 import java.lang.invoke.ConstantCallSite;
22 import java.lang.invoke.MethodHandle;
23 import java.lang.invoke.MethodHandles;
24 import java.lang.invoke.MethodType;
25 
26 // Tests for methods generating invoke-custom/range.
27 public class TestLinkerMethodWithRange extends TestBase {
28     @CalledByIndy(
29         bootstrapMethod =
30                 @BootstrapMethod(
31                     enclosingType = TestLinkerMethodWithRange.class,
32                     name = "primLinkerMethod",
33                     parameterTypes = {
34                         MethodHandles.Lookup.class,
35                         String.class,
36                         MethodType.class,
37                         int.class,
38                         int.class,
39                         int.class,
40                         int.class,
41                         int.class,
42                         float.class,
43                         double.class,
44                         String.class,
45                         Class.class,
46                         long.class
47                     }
48                 ),
49         fieldOrMethodName = "_add",
50         returnType = int.class,
51         parameterTypes = {int.class, int.class, int.class, int.class, int.class, int.class},
52         constantArgumentsForBootstrapMethod = {
53             @Constant(intValue = -1),
54             @Constant(intValue = 1),
55             @Constant(intValue = (int) 'a'),
56             @Constant(intValue = 1024),
57             @Constant(intValue = 1),
58             @Constant(floatValue = 11.1f),
59             @Constant(doubleValue = 2.2),
60             @Constant(stringValue = "Hello"),
61             @Constant(classValue = TestLinkerMethodWithRange.class),
62             @Constant(longValue = 123456789L)
63         }
64     )
65 
add(int a, int b, int c, int d, int e, int f)66     private static int add(int a, int b, int c, int d, int e, int f) {
67         assertNotReached();
68         return -1;
69     }
70 
71     @SuppressWarnings("unused")
_add(int a, int b, int c, int d, int e, int f)72     private static int _add(int a, int b, int c, int d, int e, int f) {
73         return a + b + c + d + e + f;
74     }
75 
76     @SuppressWarnings("unused")
primLinkerMethod( MethodHandles.Lookup caller, String name, MethodType methodType, int v1, int v2, int v3, int v4, int v5, float v6, double v7, String v8, Class<?> v9, long v10)77     private static CallSite primLinkerMethod(
78             MethodHandles.Lookup caller,
79             String name,
80             MethodType methodType,
81             int v1,
82             int v2,
83             int v3,
84             int v4,
85             int v5,
86             float v6,
87             double v7,
88             String v8,
89             Class<?> v9,
90             long v10)
91             throws Throwable {
92         System.out.println("Linking " + name + " " + methodType);
93         assertEquals(-1, v1);
94         assertEquals(1, v2);
95         assertEquals('a', v3);
96         assertEquals(1024, v4);
97         assertEquals(1, v5);
98         assertEquals(11.1f, v6);
99         assertEquals(2.2, v7);
100         assertEquals("Hello", v8);
101         assertEquals(TestLinkerMethodWithRange.class, v9);
102         assertEquals(123456789L, v10);
103         MethodHandle mh_add =
104                 caller.findStatic(TestLinkerMethodWithRange.class, name, methodType);
105         return new ConstantCallSite(mh_add);
106     }
107 
test(int u, int v, int w, int x, int y, int z)108     public static void test(int u, int v, int w, int x, int y, int z) throws Throwable {
109         assertEquals(u + v + w + x + y + z, add(u, v, w, x, y, z));
110         System.out.println(u + v + w + x + y + z);
111     }
112 
113     @CalledByIndy(
114         bootstrapMethod =
115                 @BootstrapMethod(
116                     enclosingType = TestLinkerMethodWithRange.class,
117                     name = "refLinkerMethod",
118                     parameterTypes = {
119                         MethodHandles.Lookup.class,
120                         String.class,
121                         MethodType.class,
122                     }
123                 ),
124         fieldOrMethodName = "_multiply",
125         returnType = Integer.class,
126         parameterTypes = {Double.class, Double.class, Double.class,
127                           Double.class, Double.class, Double.class},
128         constantArgumentsForBootstrapMethod = {}
129     )
130 
multiply(Double a, Double b, Double c, Double d, Double e, Double f)131     private static Double multiply(Double a, Double b, Double c, Double d, Double e, Double f) {
132         assertNotReached();
133         return 0.0;
134     }
135 
136     @SuppressWarnings("unused")
_multiply(Double a, Double b, Double c, Double d, Double e, Double f)137     private static Double _multiply(Double a, Double b, Double c, Double d, Double e, Double f) {
138         Double[] values = new Double[] { a, b, c, d, e, f };
139         Double product = 1.0;
140         for (Double value : values) {
141             if (value != null) {
142                 product *= value;
143             }
144         }
145         return product;
146     }
147 
148     @SuppressWarnings("unused")
refLinkerMethod( MethodHandles.Lookup caller, String name, MethodType methodType)149     private static CallSite refLinkerMethod(
150             MethodHandles.Lookup caller, String name, MethodType methodType) throws Throwable {
151         System.out.println("Linking " + name + " " + methodType);
152         MethodHandle mh_multiply =
153                 caller.findStatic(TestLinkerMethodWithRange.class, name, methodType);
154         return new ConstantCallSite(mh_multiply);
155     }
156 
test(Double u, Double v, Double w, Double x, Double y, Double z)157     public static void test(Double u, Double v, Double w, Double x, Double y, Double z)
158             throws Throwable {
159         Double product = 1.0;
160         if (u != null) product *= u;
161         if (v != null) product *= v;
162         if (w != null) product *= w;
163         if (x != null) product *= x;
164         if (y != null) product *= y;
165         if (z != null) product *= z;
166         assertEquals(product, multiply(u, v, w, x, y, z));
167         System.out.println(product);
168     }
169 }
170