blob: 8450a44310b66ad77f1a6b30f6360fb3ace84091 [file] [log] [blame]
Orion Hodson4c8e12e2018-05-18 08:33:20 +01001/*
2 * Copyright (C) 2018 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
17import annotations.BootstrapMethod;
18import annotations.CalledByIndy;
19import java.lang.invoke.CallSite;
20import java.lang.invoke.ConstantCallSite;
21import java.lang.invoke.MethodHandle;
22import java.lang.invoke.MethodHandles;
23import java.lang.invoke.MethodType;
24
25class TestReturnValues extends TestBase {
26 static CallSite bsm(MethodHandles.Lookup lookup, String name, MethodType methodType)
27 throws Throwable {
28 MethodHandle mh = lookup.findStatic(TestReturnValues.class, name, methodType);
29 return new ConstantCallSite(mh);
30 }
31
32 //
33 // Methods that pass through a single argument.
34 // Used to check return path.
35 //
36 static byte passThrough(byte value) {
37 return value;
38 }
39
40 static char passThrough(char value) {
41 return value;
42 }
43
44 static double passThrough(double value) {
45 return value;
46 }
47
48 static float passThrough(float value) {
49 return value;
50 }
51
52 static int passThrough(int value) {
53 return value;
54 }
55
56 static Object passThrough(Object value) {
57 return value;
58 }
59
60 static Object[] passThrough(Object[] value) {
61 return value;
62 }
63
64 static long passThrough(long value) {
65 return value;
66 }
67
68 static short passThrough(short value) {
69 return value;
70 }
71
72 static void passThrough() {}
73
74 static boolean passThrough(boolean value) {
75 return value;
76 }
77
78 // byte
79 @CalledByIndy(
80 bootstrapMethod =
81 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
82 fieldOrMethodName = "passThrough",
83 returnType = byte.class,
84 parameterTypes = {byte.class})
85 private static byte passThroughCallSite(byte value) {
86 assertNotReached();
87 return (byte) 0;
88 }
89
90 // char
91 @CalledByIndy(
92 bootstrapMethod =
93 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
94 fieldOrMethodName = "passThrough",
95 returnType = char.class,
96 parameterTypes = {char.class})
97 private static char passThroughCallSite(char value) {
98 assertNotReached();
99 return 'Z';
100 }
101
102 // double
103 @CalledByIndy(
104 bootstrapMethod =
105 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
106 fieldOrMethodName = "passThrough",
107 returnType = double.class,
108 parameterTypes = {double.class})
109 private static double passThroughCallSite(double value) {
110 assertNotReached();
111 return Double.NaN;
112 }
113
114 // float
115 @CalledByIndy(
116 bootstrapMethod =
117 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
118 fieldOrMethodName = "passThrough",
119 returnType = float.class,
120 parameterTypes = {float.class})
121 private static float passThroughCallSite(float value) {
122 assertNotReached();
123 return Float.NaN;
124 }
125
126 // int
127 @CalledByIndy(
128 bootstrapMethod =
129 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
130 fieldOrMethodName = "passThrough",
131 returnType = int.class,
132 parameterTypes = {int.class})
133 private static int passThroughCallSite(int value) {
134 assertNotReached();
135 return 0;
136 }
137
138 // long
139 @CalledByIndy(
140 bootstrapMethod =
141 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
142 fieldOrMethodName = "passThrough",
143 returnType = long.class,
144 parameterTypes = {long.class})
145 private static long passThroughCallSite(long value) {
146 assertNotReached();
147 return Long.MIN_VALUE;
148 }
149
150 // Object
151 @CalledByIndy(
152 bootstrapMethod =
153 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
154 fieldOrMethodName = "passThrough",
155 returnType = Object.class,
156 parameterTypes = {Object.class})
157 private static Object passThroughCallSite(Object value) {
158 assertNotReached();
159 return null;
160 }
161
162 // Object[]
163 @CalledByIndy(
164 bootstrapMethod =
165 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
166 fieldOrMethodName = "passThrough",
167 returnType = Object[].class,
168 parameterTypes = {Object[].class})
169 private static Object[] passThroughCallSite(Object[] value) {
170 assertNotReached();
171 return null;
172 }
173
174 // short
175 @CalledByIndy(
176 bootstrapMethod =
177 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
178 fieldOrMethodName = "passThrough",
179 returnType = short.class,
180 parameterTypes = {short.class})
181 private static short passThroughCallSite(short value) {
182 assertNotReached();
183 return (short) 0;
184 }
185
186 // void
187 @CalledByIndy(
188 bootstrapMethod =
189 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
190 fieldOrMethodName = "passThrough",
191 returnType = void.class,
192 parameterTypes = {})
193 private static void passThroughCallSite() {
194 assertNotReached();
195 }
196
197 // boolean
198 @CalledByIndy(
199 bootstrapMethod =
200 @BootstrapMethod(enclosingType = TestReturnValues.class, name = "bsm"),
201 fieldOrMethodName = "passThrough",
202 returnType = boolean.class,
203 parameterTypes = {boolean.class})
204 private static boolean passThroughCallSite(boolean value) {
205 assertNotReached();
206 return false;
207 }
208
209 private static void testByteReturnValues() {
210 byte[] values = {Byte.MIN_VALUE, Byte.MAX_VALUE};
211 for (byte value : values) {
212 assertEquals(value, (byte) passThroughCallSite(value));
213 }
214 }
215
216 private static void testCharReturnValues() {
217 char[] values = {
218 Character.MIN_VALUE,
219 Character.MAX_HIGH_SURROGATE,
220 Character.MAX_LOW_SURROGATE,
221 Character.MAX_VALUE
222 };
223 for (char value : values) {
224 assertEquals(value, (char) passThroughCallSite(value));
225 }
226 }
227
228 private static void testDoubleReturnValues() {
229 double[] values = {
230 Double.MIN_VALUE,
231 Double.MIN_NORMAL,
232 Double.NaN,
233 Double.POSITIVE_INFINITY,
234 Double.NEGATIVE_INFINITY,
235 Double.MAX_VALUE
236 };
237 for (double value : values) {
238 assertEquals(value, (double) passThroughCallSite(value));
239 }
240 }
241
242 private static void testFloatReturnValues() {
243 float[] values = {
244 Float.MIN_VALUE,
245 Float.MIN_NORMAL,
246 Float.NaN,
247 Float.POSITIVE_INFINITY,
248 Float.NEGATIVE_INFINITY,
249 Float.MAX_VALUE
250 };
251 for (float value : values) {
252 assertEquals(value, (float) passThroughCallSite(value));
253 }
254 }
255
256 private static void testIntReturnValues() {
257 int[] values = {Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.SIZE, -Integer.SIZE};
258 for (int value : values) {
259 assertEquals(value, (int) passThroughCallSite(value));
260 }
261 }
262
263 private static void testLongReturnValues() {
264 long[] values = {Long.MIN_VALUE, Long.MAX_VALUE, (long) Long.SIZE, (long) -Long.SIZE};
265 for (long value : values) {
266 assertEquals(value, (long) passThroughCallSite(value));
267 }
268 }
269
270 private static void testObjectReturnValues() {
271 Object[] values = {null, "abc", Integer.valueOf(123)};
272 for (Object value : values) {
273 assertEquals(value, (Object) passThroughCallSite(value));
274 }
275
276 Object[] otherValues = (Object[]) passThroughCallSite(values);
277 assertEquals(values.length, otherValues.length);
278 for (int i = 0; i < otherValues.length; ++i) {
279 assertEquals(values[i], otherValues[i]);
280 }
281 }
282
283 private static void testShortReturnValues() {
284 short[] values = {
285 Short.MIN_VALUE, Short.MAX_VALUE, (short) Short.SIZE, (short) -Short.SIZE
286 };
287 for (short value : values) {
288 assertEquals(value, (short) passThroughCallSite(value));
289 }
290 }
291
292 private static void testVoidReturnValues() {
293 long l = Long.MIN_VALUE;
294 double d = Double.MIN_VALUE;
295 passThroughCallSite(); // Initializes call site
296 assertEquals(Long.MIN_VALUE, l);
297 assertEquals(Double.MIN_VALUE, d);
298
299 l = Long.MAX_VALUE;
300 d = Double.MAX_VALUE;
301 passThroughCallSite(); // re-uses existing call site
302 assertEquals(Long.MAX_VALUE, l);
303 assertEquals(Double.MAX_VALUE, d);
304 }
305
306 private static void testBooleanReturnValues() {
307 boolean[] values = {true, false, true, false, false};
308 for (boolean value : values) {
309 assertEquals(value, (boolean) passThroughCallSite(value));
310 }
311 }
312
313 public static void test() {
314 System.out.println(TestReturnValues.class.getName());
315 // Two passes here - the first is for the call site creation and invoke path, the second
316 // for the lookup and invoke path.
317 for (int pass = 0; pass < 2; ++pass) {
318 testByteReturnValues(); // B
319 testCharReturnValues(); // C
320 testDoubleReturnValues(); // D
321 testFloatReturnValues(); // F
322 testIntReturnValues(); // I
323 testLongReturnValues(); // J
324 testObjectReturnValues(); // L
325 testShortReturnValues(); // S
326 testVoidReturnValues(); // S
327 testBooleanReturnValues(); // Z
328 }
329 }
330}