1 /*
2  * Copyright (C) 2017 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 package invokecustom;
18 
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 import java.util.Arrays;
26 import java.util.List;
27 import java.util.stream.Collectors;
28 
29 abstract class Super {
targetMethodTest4()30   public void targetMethodTest4() {
31     System.out.println("targetMethodTest4 from Super");
32   }
33 
helperMethodTest9()34   public abstract void helperMethodTest9();
35 }
36 
37 public class InvokeCustom extends Super implements Runnable {
38 
InvokeCustom()39   public InvokeCustom() {}
InvokeCustom(int i)40   public InvokeCustom(int i) {
41     System.out.println("InvokeCustom.<init>(" + i + ")");
42   }
43 
targetMethodTest1()44   private static void targetMethodTest1() {
45     System.out.println("Hello World!");
46   }
47 
targetMethodTest2(boolean z, byte b, char c, short s, int i, float f, long l, double d, String str)48   private static void targetMethodTest2(boolean z, byte b, char c, short s, int i, float f, long l,
49       double d, String str) {
50     System.out.println(z);
51     System.out.println(b);
52     System.out.println(c);
53     System.out.println(s);
54     System.out.println(i);
55     System.out.println(f);
56     System.out.println(l);
57     System.out.println(d);
58     System.out.println(str);
59   }
60 
targetMethodTest3()61   private static void targetMethodTest3() {
62     System.out.println("targetMethodTest3 from InvokeCustom");
63   }
64 
65   @Override
targetMethodTest4()66   public void targetMethodTest4() {
67     // The generated code should be calling Super.targetMethodTest4.
68     System.out.println("targetMethodTest4 from InvokeCustom (oops!)");
69   }
70 
targetMethodTest5(int x, int y, int total)71   public static int targetMethodTest5(int x, int y, int total) {
72     int calculated = x + y;
73     System.out.println("targetMethodTest5 " + x + " + " + y + " = " + calculated);
74     if (calculated != total) {
75         System.out.println("Failed " + calculated + " != " + total);
76     }
77     return calculated;
78   }
79 
targetMethodTest6(long x, long y, long total)80   public static long targetMethodTest6(long x, long y, long total) {
81     long calculated = x + y;
82     System.out.println("targetMethodTest6 " + x + " + " + y + " = " + calculated);
83     if (calculated != total) {
84         System.out.println("Failed " + calculated + " != " + total);
85     }
86     return calculated;
87   }
88 
targetMethodTest7(float x, float y, double product)89   public static double targetMethodTest7(float x, float y, double product) {
90     double calculated = x * y;
91     System.out.println("targetMethodTest7 " + x + " * " + y + " = " + calculated);
92     if (calculated != product) {
93       System.out.println("Failed " + calculated + " != " + product);
94     }
95     return calculated;
96   }
97 
targetMethodTest8(String s)98   public static void targetMethodTest8(String s) {
99     System.out.println("targetMethodTest8 " + s);
100   }
101 
102   private static int staticFieldTest9 = 0;
103 
checkStaticFieldTest9(MethodHandle getter, MethodHandle setter)104   private static void checkStaticFieldTest9(MethodHandle getter, MethodHandle setter)
105       throws Throwable {
106     final int NEW_VALUE = 0x76543210;
107     int oldValue = (int) getter.invokeExact();
108     setter.invokeExact(NEW_VALUE);
109     int newValue = (int) getter.invokeExact();
110     System.out.print("checkStaticFieldTest9: old " + oldValue + " new " + newValue +
111                      " expected " + NEW_VALUE + " ");
112     System.out.println((newValue == NEW_VALUE) ? "OK" : "ERROR");
113   }
114 
115   private float fieldTest9 = 0.0f;
116 
checkFieldTest9(MethodHandle getter, MethodHandle setter)117   private void checkFieldTest9(MethodHandle getter, MethodHandle setter)
118       throws Throwable {
119     final float NEW_VALUE = 1.99e-19f;
120     float oldValue = (float) getter.invokeExact(this);
121     setter.invokeExact(this, NEW_VALUE);
122     float newValue = (float) getter.invokeExact(this);
123     System.out.print("checkFieldTest9: old " + oldValue + " new " + newValue +
124                      " expected " + NEW_VALUE + " ");
125     System.out.println((newValue == NEW_VALUE) ? "OK" : "ERROR");
126   }
127 
helperMethodTest9()128   public void helperMethodTest9() {
129     System.out.println("helperMethodTest9 in " + InvokeCustom.class);
130   }
131 
targetMethodTest9()132   private static void targetMethodTest9() {
133     System.out.println("targetMethodTest9()");
134   }
135 
run()136   public void run() {
137     System.out.println("run() for Test9");
138   }
139 
bsmLookupStatic(MethodHandles.Lookup caller, String name, MethodType type)140   public static CallSite bsmLookupStatic(MethodHandles.Lookup caller, String name, MethodType type)
141       throws NoSuchMethodException, IllegalAccessException {
142     System.out.println("bsmLookupStatic []");
143     final MethodHandles.Lookup lookup = MethodHandles.lookup();
144     final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
145     return new ConstantCallSite(targetMH.asType(type));
146   }
147 
bsmLookupStaticWithExtraArgs( MethodHandles.Lookup caller, String name, MethodType type, int i, long l, float f, double d)148   public static CallSite bsmLookupStaticWithExtraArgs(
149       MethodHandles.Lookup caller, String name, MethodType type, int i, long l, float f, double d)
150       throws NoSuchMethodException, IllegalAccessException {
151     System.out.println("bsmLookupStaticWithExtraArgs [" + i + ", " + l + ", " + f + ", " + d + "]");
152     final MethodHandles.Lookup lookup = MethodHandles.lookup();
153     final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
154     return new ConstantCallSite(targetMH.asType(type));
155   }
156 
bsmCreateCallSite( MethodHandles.Lookup caller, String name, MethodType type, MethodHandle mh)157   public static CallSite bsmCreateCallSite(
158       MethodHandles.Lookup caller, String name, MethodType type, MethodHandle mh)
159       throws Throwable {
160     System.out.println("bsmCreateCallSite [" + mh + "]");
161     return new ConstantCallSite(mh);
162   }
163 
privateMethodTest9()164   private void privateMethodTest9() {
165     System.out.println("InvokeCustom.privateMethodTest9()");
166   }
167 
bsmLookupTest9(MethodHandles.Lookup caller, String name, MethodType type, MethodHandle staticGetter, MethodHandle staticSetter, MethodHandle fieldGetter, MethodHandle fieldSetter, MethodHandle instanceInvoke, MethodHandle constructor, MethodHandle interfaceInvoke, MethodHandle privateInvoke)168   public static CallSite bsmLookupTest9(MethodHandles.Lookup caller, String name, MethodType type,
169                                         MethodHandle staticGetter,  MethodHandle staticSetter,
170                                         MethodHandle fieldGetter, MethodHandle fieldSetter,
171                                         MethodHandle instanceInvoke, MethodHandle constructor,
172                                         MethodHandle interfaceInvoke, MethodHandle privateInvoke)
173           throws Throwable {
174     System.out.println("bsmLookupTest9 [" + staticGetter + ", " + staticSetter + ", " +
175                        fieldGetter + ", " + fieldSetter + "]");
176     System.out.println(name + " " + type);
177 
178     // Check constant method handles passed can be invoked.
179     checkStaticFieldTest9(staticGetter, staticSetter);
180     InvokeCustom instance = new InvokeCustom();
181     instance.checkFieldTest9(fieldGetter, fieldSetter);
182 
183     // Check virtual method.
184     instanceInvoke.invokeExact(instance);
185 
186     InvokeCustom instance2 = (InvokeCustom) constructor.invokeExact(3);
187     interfaceInvoke.invoke(instance2);
188     privateInvoke.invoke(instance2);
189 
190     final MethodHandles.Lookup lookup = MethodHandles.lookup();
191     final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
192     return new ConstantCallSite(targetMH.asType(type));
193   }
194 
lambdaTest()195   public static void lambdaTest() {
196     List<String> strings = Arrays.asList(new String[] { "Three", "One", "FortyTwo" });
197     String sample = strings.stream().filter(x -> "One".equals(x.trim()))
198         .map(String::trim).findAny().orElse("");
199     strings.stream().forEach(System.out::println);
200   }
201 }
202