1 /* 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 17 import annotations.BootstrapMethod; 18 import annotations.CalledByIndy; 19 import java.lang.invoke.CallSite; 20 import java.lang.invoke.ConstantCallSite; 21 import java.lang.invoke.MethodHandle; 22 import java.lang.invoke.MethodHandles; 23 import java.lang.invoke.MethodType; 24 25 class TestReturnValues extends TestBase { bsm(MethodHandles.Lookup lookup, String name, MethodType methodType)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 // passThrough(byte value)36 static byte passThrough(byte value) { 37 return value; 38 } 39 passThrough(char value)40 static char passThrough(char value) { 41 return value; 42 } 43 passThrough(double value)44 static double passThrough(double value) { 45 return value; 46 } 47 passThrough(float value)48 static float passThrough(float value) { 49 return value; 50 } 51 passThrough(int value)52 static int passThrough(int value) { 53 return value; 54 } 55 passThrough(Object value)56 static Object passThrough(Object value) { 57 return value; 58 } 59 passThrough(Object[] value)60 static Object[] passThrough(Object[] value) { 61 return value; 62 } 63 passThrough(long value)64 static long passThrough(long value) { 65 return value; 66 } 67 passThrough(short value)68 static short passThrough(short value) { 69 return value; 70 } 71 passThrough()72 static void passThrough() {} 73 passThrough(boolean value)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}) passThroughCallSite(byte value)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}) passThroughCallSite(char value)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}) passThroughCallSite(double value)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}) passThroughCallSite(float value)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}) passThroughCallSite(int value)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}) passThroughCallSite(long value)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}) passThroughCallSite(Object value)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}) passThroughCallSite(Object[] value)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}) passThroughCallSite(short value)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 = {}) passThroughCallSite()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}) passThroughCallSite(boolean value)204 private static boolean passThroughCallSite(boolean value) { 205 assertNotReached(); 206 return false; 207 } 208 testByteReturnValues()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 testCharReturnValues()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 testDoubleReturnValues()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 testFloatReturnValues()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 testIntReturnValues()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 testLongReturnValues()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 testObjectReturnValues()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 testShortReturnValues()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 testVoidReturnValues()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 testBooleanReturnValues()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 test()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 } 331