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