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
17package invokecustom;
18
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
25import java.util.Arrays;
26import java.util.List;
27import java.util.stream.Collectors;
28
29abstract class Super {
30  public void targetMethodTest4() {
31    System.out.println("targetMethodTest4 from Super");
32  }
33
34  public abstract void helperMethodTest9();
35}
36
37public class InvokeCustom extends Super implements Runnable {
38
39  public InvokeCustom() {}
40  public InvokeCustom(int i) {
41    System.out.println("InvokeCustom.<init>(" + i + ")");
42  }
43
44  private static void targetMethodTest1() {
45    System.out.println("Hello World!");
46  }
47
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
61  private static void targetMethodTest3() {
62    System.out.println("targetMethodTest3 from InvokeCustom");
63  }
64
65  @Override
66  public void targetMethodTest4() {
67    // The generated code should be calling Super.targetMethodTest4.
68    System.out.println("targetMethodTest4 from InvokeCustom (oops!)");
69  }
70
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
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
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
98  public static void targetMethodTest8(String s) {
99    System.out.println("targetMethodTest8 " + s);
100  }
101
102  private static int staticFieldTest9 = 0;
103
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
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
128  public void helperMethodTest9() {
129    System.out.println("helperMethodTest9 in " + InvokeCustom.class);
130  }
131
132  private static void targetMethodTest9() {
133    System.out.println("targetMethodTest9()");
134  }
135
136  public void run() {
137    System.out.println("run() for Test9");
138  }
139
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
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
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
164  private void privateMethodTest9() {
165    System.out.println("InvokeCustom.privateMethodTest9()");
166  }
167
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
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