/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package invokecustom;
import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
abstract class Super {
public void targetMethodTest4() {
System.out.println("targetMethodTest4 from Super");
}
public abstract void helperMethodTest9();
}
public class InvokeCustom extends Super implements Runnable {
public InvokeCustom() {}
public InvokeCustom(int i) {
System.out.println("InvokeCustom.<init>(" + i + ")");
}
private static void targetMethodTest1() {
System.out.println("Hello World!");
}
private static void targetMethodTest2(boolean z, byte b, char c, short s, int i, float f, long l,
double d, String str) {
System.out.println(z);
System.out.println(b);
System.out.println(c);
System.out.println(s);
System.out.println(i);
System.out.println(f);
System.out.println(l);
System.out.println(d);
System.out.println(str);
}
private static void targetMethodTest3() {
System.out.println("targetMethodTest3 from InvokeCustom");
}
@Override
public void targetMethodTest4() {
// The generated code should be calling Super.targetMethodTest4.
System.out.println("targetMethodTest4 from InvokeCustom (oops!)");
}
public static int targetMethodTest5(int x, int y, int total) {
int calculated = x + y;
System.out.println("targetMethodTest5 " + x + " + " + y + " = " + calculated);
if (calculated != total) {
System.out.println("Failed " + calculated + " != " + total);
}
return calculated;
}
public static long targetMethodTest6(long x, long y, long total) {
long calculated = x + y;
System.out.println("targetMethodTest6 " + x + " + " + y + " = " + calculated);
if (calculated != total) {
System.out.println("Failed " + calculated + " != " + total);
}
return calculated;
}
public static double targetMethodTest7(float x, float y, double product) {
double calculated = x * y;
System.out.println("targetMethodTest7 " + x + " * " + y + " = " + calculated);
if (calculated != product) {
System.out.println("Failed " + calculated + " != " + product);
}
return calculated;
}
public static void targetMethodTest8(String s) {
System.out.println("targetMethodTest8 " + s);
}
private static int staticFieldTest9 = 0;
private static void checkStaticFieldTest9(MethodHandle getter, MethodHandle setter)
throws Throwable {
final int NEW_VALUE = 0x76543210;
int oldValue = (int) getter.invokeExact();
setter.invokeExact(NEW_VALUE);
int newValue = (int) getter.invokeExact();
System.out.print("checkStaticFieldTest9: old " + oldValue + " new " + newValue +
" expected " + NEW_VALUE + " ");
System.out.println((newValue == NEW_VALUE) ? "OK" : "ERROR");
}
private float fieldTest9 = 0.0f;
private void checkFieldTest9(MethodHandle getter, MethodHandle setter)
throws Throwable {
final float NEW_VALUE = 1.99e-19f;
float oldValue = (float) getter.invokeExact(this);
setter.invokeExact(this, NEW_VALUE);
float newValue = (float) getter.invokeExact(this);
System.out.print("checkFieldTest9: old " + oldValue + " new " + newValue +
" expected " + NEW_VALUE + " ");
System.out.println((newValue == NEW_VALUE) ? "OK" : "ERROR");
}
public void helperMethodTest9() {
System.out.println("helperMethodTest9 in " + InvokeCustom.class);
}
private static void targetMethodTest9() {
System.out.println("targetMethodTest9()");
}
public void run() {
System.out.println("run() for Test9");
}
public static CallSite bsmLookupStatic(MethodHandles.Lookup caller, String name, MethodType type)
throws NoSuchMethodException, IllegalAccessException {
System.out.println("bsmLookupStatic []");
final MethodHandles.Lookup lookup = MethodHandles.lookup();
final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
return new ConstantCallSite(targetMH.asType(type));
}
public static CallSite bsmLookupStaticWithExtraArgs(
MethodHandles.Lookup caller, String name, MethodType type, int i, long l, float f, double d)
throws NoSuchMethodException, IllegalAccessException {
System.out.println("bsmLookupStaticWithExtraArgs [" + i + ", " + l + ", " + f + ", " + d + "]");
final MethodHandles.Lookup lookup = MethodHandles.lookup();
final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
return new ConstantCallSite(targetMH.asType(type));
}
public static CallSite bsmCreateCallSite(
MethodHandles.Lookup caller, String name, MethodType type, MethodHandle mh)
throws Throwable {
System.out.println("bsmCreateCallSite [" + mh + "]");
return new ConstantCallSite(mh);
}
private void privateMethodTest9() {
System.out.println("InvokeCustom.privateMethodTest9()");
}
public static CallSite bsmLookupTest9(MethodHandles.Lookup caller, String name, MethodType type,
MethodHandle staticGetter, MethodHandle staticSetter,
MethodHandle fieldGetter, MethodHandle fieldSetter,
MethodHandle instanceInvoke, MethodHandle constructor,
MethodHandle interfaceInvoke, MethodHandle privateInvoke)
throws Throwable {
System.out.println("bsmLookupTest9 [" + staticGetter + ", " + staticSetter + ", " +
fieldGetter + ", " + fieldSetter + "]");
System.out.println(name + " " + type);
// Check constant method handles passed can be invoked.
checkStaticFieldTest9(staticGetter, staticSetter);
InvokeCustom instance = new InvokeCustom();
instance.checkFieldTest9(fieldGetter, fieldSetter);
// Check virtual method.
instanceInvoke.invokeExact(instance);
InvokeCustom instance2 = (InvokeCustom) constructor.invokeExact(3);
interfaceInvoke.invoke(instance2);
privateInvoke.invoke(instance2);
final MethodHandles.Lookup lookup = MethodHandles.lookup();
final MethodHandle targetMH = lookup.findStatic(lookup.lookupClass(), name, type);
return new ConstantCallSite(targetMH.asType(type));
}
public static void lambdaTest() {
List<String> strings = Arrays.asList(new String[] { "Three", "One", "FortyTwo" });
String sample = strings.stream().filter(x -> "One".equals(x.trim()))
.map(String::trim).findAny().orElse("");
strings.stream().forEach(System.out::println);
}
}