xref: /aosp_15_r20/art/test/952-invoke-custom/src/TestInvocationKinds.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker import annotations.BootstrapMethod;
18*795d594fSAndroid Build Coastguard Worker import annotations.CalledByIndy;
19*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.CallSite;
20*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.ConstantCallSite;
21*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandle;
22*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandles;
23*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodType;
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker class TestInvocationKinds extends TestBase {
26*795d594fSAndroid Build Coastguard Worker     private static int static_field;
27*795d594fSAndroid Build Coastguard Worker     private double instance_field;
28*795d594fSAndroid Build Coastguard Worker 
lookupStaticFieldGetter( MethodHandles.Lookup lookup, String name, MethodType methodType)29*795d594fSAndroid Build Coastguard Worker     static CallSite lookupStaticFieldGetter(
30*795d594fSAndroid Build Coastguard Worker             MethodHandles.Lookup lookup, String name, MethodType methodType) throws Throwable {
31*795d594fSAndroid Build Coastguard Worker         // methodType = "()LfieldType;"
32*795d594fSAndroid Build Coastguard Worker         MethodHandle mh =
33*795d594fSAndroid Build Coastguard Worker                 lookup.findStaticGetter(TestInvocationKinds.class, name, methodType.returnType());
34*795d594fSAndroid Build Coastguard Worker         return new ConstantCallSite(mh);
35*795d594fSAndroid Build Coastguard Worker     }
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker     @CalledByIndy(
38*795d594fSAndroid Build Coastguard Worker         bootstrapMethod =
39*795d594fSAndroid Build Coastguard Worker                 @BootstrapMethod(
40*795d594fSAndroid Build Coastguard Worker                     enclosingType = TestInvocationKinds.class,
41*795d594fSAndroid Build Coastguard Worker                     name = "lookupStaticFieldSetter"
42*795d594fSAndroid Build Coastguard Worker                 ),
43*795d594fSAndroid Build Coastguard Worker         fieldOrMethodName = "static_field",
44*795d594fSAndroid Build Coastguard Worker         returnType = void.class,
45*795d594fSAndroid Build Coastguard Worker         parameterTypes = {int.class}
46*795d594fSAndroid Build Coastguard Worker     )
setStaticField(int value)47*795d594fSAndroid Build Coastguard Worker     private static void setStaticField(int value) {
48*795d594fSAndroid Build Coastguard Worker         assertNotReached();
49*795d594fSAndroid Build Coastguard Worker     }
50*795d594fSAndroid Build Coastguard Worker 
lookupStaticFieldSetter( MethodHandles.Lookup lookup, String name, MethodType methodType)51*795d594fSAndroid Build Coastguard Worker     static CallSite lookupStaticFieldSetter(
52*795d594fSAndroid Build Coastguard Worker             MethodHandles.Lookup lookup, String name, MethodType methodType) throws Throwable {
53*795d594fSAndroid Build Coastguard Worker         // methodType = "(LfieldType;)V"
54*795d594fSAndroid Build Coastguard Worker         MethodHandle mh =
55*795d594fSAndroid Build Coastguard Worker                 lookup.findStaticSetter(
56*795d594fSAndroid Build Coastguard Worker                         TestInvocationKinds.class, name, methodType.parameterType(0));
57*795d594fSAndroid Build Coastguard Worker         return new ConstantCallSite(mh);
58*795d594fSAndroid Build Coastguard Worker     }
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker     @CalledByIndy(
61*795d594fSAndroid Build Coastguard Worker         bootstrapMethod =
62*795d594fSAndroid Build Coastguard Worker                 @BootstrapMethod(
63*795d594fSAndroid Build Coastguard Worker                     enclosingType = TestInvocationKinds.class,
64*795d594fSAndroid Build Coastguard Worker                     name = "lookupStaticFieldGetter"
65*795d594fSAndroid Build Coastguard Worker                 ),
66*795d594fSAndroid Build Coastguard Worker         fieldOrMethodName = "static_field",
67*795d594fSAndroid Build Coastguard Worker         returnType = int.class,
68*795d594fSAndroid Build Coastguard Worker         parameterTypes = {}
69*795d594fSAndroid Build Coastguard Worker     )
getStaticField()70*795d594fSAndroid Build Coastguard Worker     private static int getStaticField() {
71*795d594fSAndroid Build Coastguard Worker         assertNotReached();
72*795d594fSAndroid Build Coastguard Worker         return 0;
73*795d594fSAndroid Build Coastguard Worker     }
74*795d594fSAndroid Build Coastguard Worker 
lookupInstanceFieldSetter( MethodHandles.Lookup lookup, String name, MethodType methodType)75*795d594fSAndroid Build Coastguard Worker     static CallSite lookupInstanceFieldSetter(
76*795d594fSAndroid Build Coastguard Worker             MethodHandles.Lookup lookup, String name, MethodType methodType) throws Throwable {
77*795d594fSAndroid Build Coastguard Worker         // methodType = "(Lreceiver;LfieldType;)V"
78*795d594fSAndroid Build Coastguard Worker         MethodHandle mh =
79*795d594fSAndroid Build Coastguard Worker                 lookup.findSetter(methodType.parameterType(0), name, methodType.parameterType(1));
80*795d594fSAndroid Build Coastguard Worker         return new ConstantCallSite(mh);
81*795d594fSAndroid Build Coastguard Worker     }
82*795d594fSAndroid Build Coastguard Worker 
83*795d594fSAndroid Build Coastguard Worker     @CalledByIndy(
84*795d594fSAndroid Build Coastguard Worker         bootstrapMethod =
85*795d594fSAndroid Build Coastguard Worker                 @BootstrapMethod(
86*795d594fSAndroid Build Coastguard Worker                     enclosingType = TestInvocationKinds.class,
87*795d594fSAndroid Build Coastguard Worker                     name = "lookupInstanceFieldSetter"
88*795d594fSAndroid Build Coastguard Worker                 ),
89*795d594fSAndroid Build Coastguard Worker         fieldOrMethodName = "instance_field",
90*795d594fSAndroid Build Coastguard Worker         returnType = void.class,
91*795d594fSAndroid Build Coastguard Worker         parameterTypes = {TestInvocationKinds.class, double.class}
92*795d594fSAndroid Build Coastguard Worker     )
setInstanceField(TestInvocationKinds instance, double value)93*795d594fSAndroid Build Coastguard Worker     private static void setInstanceField(TestInvocationKinds instance, double value) {
94*795d594fSAndroid Build Coastguard Worker         assertNotReached();
95*795d594fSAndroid Build Coastguard Worker         instance.instance_field = Double.NaN;
96*795d594fSAndroid Build Coastguard Worker     }
97*795d594fSAndroid Build Coastguard Worker 
lookupInstanceFieldGetter( MethodHandles.Lookup lookup, String name, MethodType methodType)98*795d594fSAndroid Build Coastguard Worker     static CallSite lookupInstanceFieldGetter(
99*795d594fSAndroid Build Coastguard Worker             MethodHandles.Lookup lookup, String name, MethodType methodType) throws Throwable {
100*795d594fSAndroid Build Coastguard Worker         // methodType = "(Lreceiver;)LfieldType;"
101*795d594fSAndroid Build Coastguard Worker         MethodHandle mh =
102*795d594fSAndroid Build Coastguard Worker                 lookup.findGetter(methodType.parameterType(0), name, methodType.returnType());
103*795d594fSAndroid Build Coastguard Worker         return new ConstantCallSite(mh);
104*795d594fSAndroid Build Coastguard Worker     }
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker     @CalledByIndy(
107*795d594fSAndroid Build Coastguard Worker         bootstrapMethod =
108*795d594fSAndroid Build Coastguard Worker                 @BootstrapMethod(
109*795d594fSAndroid Build Coastguard Worker                     enclosingType = TestInvocationKinds.class,
110*795d594fSAndroid Build Coastguard Worker                     name = "lookupInstanceFieldGetter"
111*795d594fSAndroid Build Coastguard Worker                 ),
112*795d594fSAndroid Build Coastguard Worker         fieldOrMethodName = "instance_field",
113*795d594fSAndroid Build Coastguard Worker         returnType = double.class,
114*795d594fSAndroid Build Coastguard Worker         parameterTypes = {TestInvocationKinds.class}
115*795d594fSAndroid Build Coastguard Worker     )
getInstanceField(TestInvocationKinds instance)116*795d594fSAndroid Build Coastguard Worker     private static double getInstanceField(TestInvocationKinds instance) {
117*795d594fSAndroid Build Coastguard Worker         assertNotReached();
118*795d594fSAndroid Build Coastguard Worker         return Double.NaN;
119*795d594fSAndroid Build Coastguard Worker     }
120*795d594fSAndroid Build Coastguard Worker 
testStaticFieldAccessors()121*795d594fSAndroid Build Coastguard Worker     private static void testStaticFieldAccessors() {
122*795d594fSAndroid Build Coastguard Worker         System.out.println("testStaticFieldAccessors");
123*795d594fSAndroid Build Coastguard Worker         setStaticField(3);
124*795d594fSAndroid Build Coastguard Worker         assertEquals(static_field, 3);
125*795d594fSAndroid Build Coastguard Worker         setStaticField(4);
126*795d594fSAndroid Build Coastguard Worker         assertEquals(static_field, 4);
127*795d594fSAndroid Build Coastguard Worker         assertEquals(static_field, getStaticField());
128*795d594fSAndroid Build Coastguard Worker         static_field = Integer.MAX_VALUE;
129*795d594fSAndroid Build Coastguard Worker         assertEquals(Integer.MAX_VALUE, getStaticField());
130*795d594fSAndroid Build Coastguard Worker     }
131*795d594fSAndroid Build Coastguard Worker 
testInstanceFieldAccessors()132*795d594fSAndroid Build Coastguard Worker     private static void testInstanceFieldAccessors() {
133*795d594fSAndroid Build Coastguard Worker         System.out.println("testInstanceFieldAccessors");
134*795d594fSAndroid Build Coastguard Worker         TestInvocationKinds instance = new TestInvocationKinds();
135*795d594fSAndroid Build Coastguard Worker         instance.instance_field = Double.MIN_VALUE;
136*795d594fSAndroid Build Coastguard Worker         setInstanceField(instance, Math.PI);
137*795d594fSAndroid Build Coastguard Worker         assertEquals(Math.PI, instance.instance_field);
138*795d594fSAndroid Build Coastguard Worker         instance.instance_field = Math.E;
139*795d594fSAndroid Build Coastguard Worker         assertEquals(Math.E, getInstanceField(instance));
140*795d594fSAndroid Build Coastguard Worker     }
141*795d594fSAndroid Build Coastguard Worker 
lookupVirtual( MethodHandles.Lookup lookup, String name, MethodType methodType)142*795d594fSAndroid Build Coastguard Worker     private static CallSite lookupVirtual(
143*795d594fSAndroid Build Coastguard Worker             MethodHandles.Lookup lookup, String name, MethodType methodType) throws Throwable {
144*795d594fSAndroid Build Coastguard Worker         // To get the point-of-use and invokedynamic to work the methodType here has the
145*795d594fSAndroid Build Coastguard Worker         // receiver type as the leading paramter which needs to be dropped for findVirtual().
146*795d594fSAndroid Build Coastguard Worker         MethodType mt = methodType.dropParameterTypes(0, 1);
147*795d594fSAndroid Build Coastguard Worker         MethodHandle mh = lookup.findVirtual(TestInvocationKinds.class, name, mt);
148*795d594fSAndroid Build Coastguard Worker         return new ConstantCallSite(mh);
149*795d594fSAndroid Build Coastguard Worker     }
150*795d594fSAndroid Build Coastguard Worker 
151*795d594fSAndroid Build Coastguard Worker     @CalledByIndy(
152*795d594fSAndroid Build Coastguard Worker         bootstrapMethod =
153*795d594fSAndroid Build Coastguard Worker                 @BootstrapMethod(enclosingType = TestInvocationKinds.class, name = "lookupVirtual"),
154*795d594fSAndroid Build Coastguard Worker         fieldOrMethodName = "getMaxIntegerValue",
155*795d594fSAndroid Build Coastguard Worker         returnType = int.class,
156*795d594fSAndroid Build Coastguard Worker         parameterTypes = {TestInvocationKinds.class, int.class, int.class}
157*795d594fSAndroid Build Coastguard Worker     )
maxIntegerValue(TestInvocationKinds receiver, int x, int y)158*795d594fSAndroid Build Coastguard Worker     private static int maxIntegerValue(TestInvocationKinds receiver, int x, int y) {
159*795d594fSAndroid Build Coastguard Worker         assertNotReached();
160*795d594fSAndroid Build Coastguard Worker         return 0;
161*795d594fSAndroid Build Coastguard Worker     }
162*795d594fSAndroid Build Coastguard Worker 
getMaxIntegerValue(int x, int y)163*795d594fSAndroid Build Coastguard Worker     public int getMaxIntegerValue(int x, int y) {
164*795d594fSAndroid Build Coastguard Worker         return x > y ? x : y;
165*795d594fSAndroid Build Coastguard Worker     }
166*795d594fSAndroid Build Coastguard Worker 
testInvokeVirtual()167*795d594fSAndroid Build Coastguard Worker     static void testInvokeVirtual() {
168*795d594fSAndroid Build Coastguard Worker         System.out.print("testInvokeVirtual => max(77, -3) = ");
169*795d594fSAndroid Build Coastguard Worker         TestInvocationKinds receiver = new TestInvocationKinds();
170*795d594fSAndroid Build Coastguard Worker         int result = maxIntegerValue(receiver, 77, -3);
171*795d594fSAndroid Build Coastguard Worker         System.out.println(result);
172*795d594fSAndroid Build Coastguard Worker     }
173*795d594fSAndroid Build Coastguard Worker 
174*795d594fSAndroid Build Coastguard Worker     static class Widget {
175*795d594fSAndroid Build Coastguard Worker         int value;
176*795d594fSAndroid Build Coastguard Worker 
Widget(int value)177*795d594fSAndroid Build Coastguard Worker         public Widget(int value) {}
178*795d594fSAndroid Build Coastguard Worker     }
179*795d594fSAndroid Build Coastguard Worker 
lookupConstructor( MethodHandles.Lookup lookup, String name, MethodType methodType)180*795d594fSAndroid Build Coastguard Worker     private static CallSite lookupConstructor(
181*795d594fSAndroid Build Coastguard Worker             MethodHandles.Lookup lookup, String name, MethodType methodType) throws Throwable {
182*795d594fSAndroid Build Coastguard Worker         // methodType = (constructorParams);classToBeConstructed
183*795d594fSAndroid Build Coastguard Worker         Class<?> cls = methodType.returnType();
184*795d594fSAndroid Build Coastguard Worker         MethodType constructorMethodType = methodType.changeReturnType(void.class);
185*795d594fSAndroid Build Coastguard Worker         MethodHandle mh = lookup.findConstructor(cls, constructorMethodType);
186*795d594fSAndroid Build Coastguard Worker         return new ConstantCallSite(mh);
187*795d594fSAndroid Build Coastguard Worker     }
188*795d594fSAndroid Build Coastguard Worker 
189*795d594fSAndroid Build Coastguard Worker     @CalledByIndy(
190*795d594fSAndroid Build Coastguard Worker         bootstrapMethod =
191*795d594fSAndroid Build Coastguard Worker                 @BootstrapMethod(
192*795d594fSAndroid Build Coastguard Worker                     enclosingType = TestInvocationKinds.class,
193*795d594fSAndroid Build Coastguard Worker                     name = "lookupConstructor"
194*795d594fSAndroid Build Coastguard Worker                 ),
195*795d594fSAndroid Build Coastguard Worker         fieldOrMethodName = "unused",
196*795d594fSAndroid Build Coastguard Worker         returnType = Widget.class,
197*795d594fSAndroid Build Coastguard Worker         parameterTypes = {int.class}
198*795d594fSAndroid Build Coastguard Worker     )
makeWidget(int v)199*795d594fSAndroid Build Coastguard Worker     private static Widget makeWidget(int v) {
200*795d594fSAndroid Build Coastguard Worker         assertNotReached();
201*795d594fSAndroid Build Coastguard Worker         return null;
202*795d594fSAndroid Build Coastguard Worker     }
203*795d594fSAndroid Build Coastguard Worker 
testConstructor()204*795d594fSAndroid Build Coastguard Worker     static void testConstructor() {
205*795d594fSAndroid Build Coastguard Worker         System.out.print("testConstructor => ");
206*795d594fSAndroid Build Coastguard Worker         Widget receiver = makeWidget(3);
207*795d594fSAndroid Build Coastguard Worker         assertEquals(Widget.class, receiver.getClass());
208*795d594fSAndroid Build Coastguard Worker         System.out.println(receiver.getClass());
209*795d594fSAndroid Build Coastguard Worker     }
210*795d594fSAndroid Build Coastguard Worker 
test()211*795d594fSAndroid Build Coastguard Worker     public static void test() {
212*795d594fSAndroid Build Coastguard Worker         System.out.println(TestInvocationKinds.class.getName());
213*795d594fSAndroid Build Coastguard Worker         testStaticFieldAccessors();
214*795d594fSAndroid Build Coastguard Worker         testInstanceFieldAccessors();
215*795d594fSAndroid Build Coastguard Worker         testInvokeVirtual();
216*795d594fSAndroid Build Coastguard Worker         testConstructor();
217*795d594fSAndroid Build Coastguard Worker     }
218*795d594fSAndroid Build Coastguard Worker }
219