1b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson/*
2b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * Copyright (C) 2017 The Android Open Source Project
3b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson *
4b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * Licensed under the Apache License, Version 2.0 (the "License");
5b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * you may not use this file except in compliance with the License.
6b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * You may obtain a copy of the License at
7b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson *
8b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson *      http://www.apache.org/licenses/LICENSE-2.0
9b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson *
10b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * Unless required by applicable law or agreed to in writing, software
11b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * distributed under the License is distributed on an "AS IS" BASIS,
12b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * See the License for the specific language governing permissions and
14b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson * limitations under the License.
15b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson */
16b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
17b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonpackage invokecustom;
18b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
19b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport java.lang.invoke.CallSite;
20b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport java.lang.invoke.ConstantCallSite;
21b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport java.lang.invoke.MethodHandle;
22b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport java.lang.invoke.MethodHandles;
23b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport java.lang.invoke.MethodType;
24b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
2573e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodsonimport java.util.Arrays;
2673e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodsonimport java.util.List;
2773e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodsonimport java.util.stream.Collectors;
2873e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodson
29b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonabstract class Super {
30b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public void targetMethodTest4() {
31b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("targetMethodTest4 from Super");
32b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
33b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
34b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public abstract void helperMethodTest9();
35b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson}
36b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
37b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonpublic class InvokeCustom extends Super implements Runnable {
38b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
39b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public InvokeCustom() {}
40b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public InvokeCustom(int i) {
41b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("InvokeCustom.<init>(" + i + ")");
42b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
43b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
44b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  private static void targetMethodTest1() {
45b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("Hello World!");
46b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
47b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
48b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  private static void targetMethodTest2(boolean z, byte b, char c, short s, int i, float f, long l,
49b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      double d, String str) {
50b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(z);
51b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(b);
52b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(c);
53b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(s);
54b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(i);
55b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(f);
56b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(l);
57b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(d);
58b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(str);
59b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
60b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
61b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  private static void targetMethodTest3() {
62b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("targetMethodTest3 from InvokeCustom");
63b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
64b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
65b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  @Override
66b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public void targetMethodTest4() {
67b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    // The generated code should be calling Super.targetMethodTest4.
68b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("targetMethodTest4 from InvokeCustom (oops!)");
69b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
70b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
71b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public static int targetMethodTest5(int x, int y, int total) {
72b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    int calculated = x + y;
73b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("targetMethodTest5 " + x + " + " + y + " = " + calculated);
74b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    if (calculated != total) {
75b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson        System.out.println("Failed " + calculated + " != " + total);
76b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    }
77b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    return calculated;
78b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
79b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
80b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public static long targetMethodTest6(long x, long y, long total) {
81b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    long calculated = x + y;
82b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("targetMethodTest6 " + x + " + " + y + " = " + calculated);
83b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    if (calculated != total) {
84b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson        System.out.println("Failed " + calculated + " != " + total);
85b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    }
86b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    return calculated;
87b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
88b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
89b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public static double targetMethodTest7(float x, float y, double product) {
90b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    double calculated = x * y;
91b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("targetMethodTest7 " + x + " * " + y + " = " + calculated);
92b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    if (calculated != product) {
93b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      System.out.println("Failed " + calculated + " != " + product);
94b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    }
95b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    return calculated;
96b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
97b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
98b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public static void targetMethodTest8(String s) {
99b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("targetMethodTest8 " + s);
100b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
101b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
102b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  private static int staticFieldTest9 = 0;
103b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
104b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  private static void checkStaticFieldTest9(MethodHandle getter, MethodHandle setter)
105b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      throws Throwable {
106b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    final int NEW_VALUE = 0x76543210;
107b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    int oldValue = (int) getter.invokeExact();
108b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    setter.invokeExact(NEW_VALUE);
109b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    int newValue = (int) getter.invokeExact();
110b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.print("checkStaticFieldTest9: old " + oldValue + " new " + newValue +
111b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson                     " expected " + NEW_VALUE + " ");
112b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println((newValue == NEW_VALUE) ? "OK" : "ERROR");
113b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
114b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
115b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  private float fieldTest9 = 0.0f;
116b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
117b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  private void checkFieldTest9(MethodHandle getter, MethodHandle setter)
118b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      throws Throwable {
119b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    final float NEW_VALUE = 1.99e-19f;
120b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    float oldValue = (float) getter.invokeExact(this);
121b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    setter.invokeExact(this, NEW_VALUE);
122b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    float newValue = (float) getter.invokeExact(this);
123b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.print("checkFieldTest9: old " + oldValue + " new " + newValue +
124b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson                     " expected " + NEW_VALUE + " ");
125b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println((newValue == NEW_VALUE) ? "OK" : "ERROR");
126b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
127b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
128b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public void helperMethodTest9() {
129b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("helperMethodTest9 in " + InvokeCustom.class);
130b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
131b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
132b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  private static void targetMethodTest9() {
133b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("targetMethodTest9()");
134b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
135b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
136b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public void run() {
137b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("run() for Test9");
138b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
139b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
140b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public static CallSite bsmLookupStatic(MethodHandles.Lookup caller, String name, MethodType type)
141b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      throws NoSuchMethodException, IllegalAccessException {
142b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("bsmLookupStatic []");
143b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    final MethodHandles.Lookup lookup = MethodHandles.lookup();
144b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
145b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    return new ConstantCallSite(targetMH.asType(type));
146b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
147b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
148b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public static CallSite bsmLookupStaticWithExtraArgs(
149b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      MethodHandles.Lookup caller, String name, MethodType type, int i, long l, float f, double d)
150b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      throws NoSuchMethodException, IllegalAccessException {
151b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("bsmLookupStaticWithExtraArgs [" + i + ", " + l + ", " + f + ", " + d + "]");
152b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    final MethodHandles.Lookup lookup = MethodHandles.lookup();
153b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
154b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    return new ConstantCallSite(targetMH.asType(type));
155b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
156b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
157b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public static CallSite bsmCreateCallSite(
158b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      MethodHandles.Lookup caller, String name, MethodType type, MethodHandle mh)
159b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson      throws Throwable {
160b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("bsmCreateCallSite [" + mh + "]");
161b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    return new ConstantCallSite(mh);
162b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
163b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
164349f7fef67de7232fce00e7cfa070c01d02b42bbOrion Hodson  private void privateMethodTest9() {
165349f7fef67de7232fce00e7cfa070c01d02b42bbOrion Hodson    System.out.println("InvokeCustom.privateMethodTest9()");
166349f7fef67de7232fce00e7cfa070c01d02b42bbOrion Hodson  }
167349f7fef67de7232fce00e7cfa070c01d02b42bbOrion Hodson
168b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  public static CallSite bsmLookupTest9(MethodHandles.Lookup caller, String name, MethodType type,
169b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson                                        MethodHandle staticGetter,  MethodHandle staticSetter,
170b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson                                        MethodHandle fieldGetter, MethodHandle fieldSetter,
171b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson                                        MethodHandle instanceInvoke, MethodHandle constructor,
172349f7fef67de7232fce00e7cfa070c01d02b42bbOrion Hodson                                        MethodHandle interfaceInvoke, MethodHandle privateInvoke)
173b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson          throws Throwable {
174b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println("bsmLookupTest9 [" + staticGetter + ", " + staticSetter + ", " +
175b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson                       fieldGetter + ", " + fieldSetter + "]");
176b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    System.out.println(name + " " + type);
177b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
178b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    // Check constant method handles passed can be invoked.
179b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    checkStaticFieldTest9(staticGetter, staticSetter);
180b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    InvokeCustom instance = new InvokeCustom();
181b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    instance.checkFieldTest9(fieldGetter, fieldSetter);
182b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
183b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    // Check virtual method.
184b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    instanceInvoke.invokeExact(instance);
185b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
186b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    InvokeCustom instance2 = (InvokeCustom) constructor.invokeExact(3);
187b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    interfaceInvoke.invoke(instance2);
188349f7fef67de7232fce00e7cfa070c01d02b42bbOrion Hodson    privateInvoke.invoke(instance2);
189b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
190b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    final MethodHandles.Lookup lookup = MethodHandles.lookup();
191b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
192b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    return new ConstantCallSite(targetMH.asType(type));
193b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson  }
19473e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodson
19573e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodson  public static void lambdaTest() {
19673e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodson    List<String> strings = Arrays.asList(new String[] { "Three", "One", "FortyTwo" });
19773e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodson    String sample = strings.stream().filter(x -> "One".equals(x.trim()))
19873e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodson        .map(String::trim).findAny().orElse("");
19973e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodson    strings.stream().forEach(System.out::println);
20073e080b9d29a10f84e1d3b8618c2b0a419689c0cOrion Hodson  }
201b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson}
202