/*
|
* Copyright (C) 2016 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.
|
*/
|
|
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles.Lookup;
|
import java.lang.invoke.MethodType;
|
import java.lang.invoke.WrongMethodTypeException;
|
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Field;
|
import java.lang.reflect.Method;
|
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
|
public class Main {
|
public static void assertTrue(boolean value) {
|
if (!value) {
|
throw new AssertionError("assertTrue value: " + value);
|
}
|
}
|
|
public static void assertFalse(boolean value) {
|
if (value) {
|
throw new AssertionError("assertTrue value: " + value);
|
}
|
}
|
|
public static void assertEquals(int i1, int i2) {
|
if (i1 == i2) { return; }
|
throw new AssertionError("assertEquals i1: " + i1 + ", i2: " + i2);
|
}
|
|
public static void assertEquals(long i1, long i2) {
|
if (i1 == i2) { return; }
|
throw new AssertionError("assertEquals l1: " + i1 + ", l2: " + i2);
|
}
|
|
public static void assertEquals(Object o, Object p) {
|
if (o == p) { return; }
|
if (o != null && p != null && o.equals(p)) { return; }
|
throw new AssertionError("assertEquals: o1: " + o + ", o2: " + p);
|
}
|
|
public static void assertEquals(String s1, String s2) {
|
if (s1 == s2) {
|
return;
|
}
|
|
if (s1 != null && s2 != null && s1.equals(s2)) {
|
return;
|
}
|
|
throw new AssertionError("assertEquals s1: " + s1 + ", s2: " + s2);
|
}
|
|
public static void fail() {
|
System.out.println("fail");
|
Thread.dumpStack();
|
}
|
|
public static void fail(String message) {
|
System.out.println("fail: " + message);
|
Thread.dumpStack();
|
}
|
|
public static int Min2Print2(int a, int b) {
|
int[] values = new int[] { a, b };
|
System.out.println("Running Main.Min2Print2(" + Arrays.toString(values) + ")");
|
return a > b ? a : b;
|
}
|
|
public static int Min2Print3(int a, int b, int c) {
|
int[] values = new int[] { a, b, c };
|
System.out.println("Running Main.Min2Print3(" + Arrays.toString(values) + ")");
|
return a > b ? a : b;
|
}
|
|
public static int Min2Print6(int a, int b, int c, int d, int e, int f) {
|
int[] values = new int[] { a, b, c, d, e, f };
|
System.out.println("Running Main.Min2Print6(" + Arrays.toString(values) + ")");
|
return a > b ? a : b;
|
}
|
|
public static int Min2Print26(int a, int b, int c, int d,
|
int e, int f, int g, int h,
|
int i, int j, int k, int l,
|
int m, int n, int o, int p,
|
int q, int r, int s, int t,
|
int u, int v, int w, int x,
|
int y, int z) {
|
int[] values = new int[] { a, b, c, d, e, f, g, h, i, j, k, l, m,
|
n, o, p, q, r, s, t, u, v, w, x, y, z };
|
System.out.println("Running Main.Min2Print26(" + Arrays.toString(values) + ")");
|
return a > b ? a : b;
|
}
|
|
public static void $opt$BasicTest() throws Throwable {
|
MethodHandle mh;
|
mh = MethodHandles.lookup().findStatic(
|
Main.class, "Min2Print2", MethodType.methodType(int.class, int.class, int.class));
|
assertEquals((int) mh.invokeExact(33, -4), 33);
|
assertEquals((int) mh.invokeExact(-4, 33), 33);
|
|
mh = MethodHandles.lookup().findStatic(
|
Main.class, "Min2Print3",
|
MethodType.methodType(int.class, int.class, int.class, int.class));
|
assertEquals((int) mh.invokeExact(33, -4, 17), 33);
|
assertEquals((int) mh.invokeExact(-4, 17, 33), 17);
|
assertEquals((int) mh.invokeExact(17, 33, -4), 33);
|
|
mh = MethodHandles.lookup().findStatic(
|
Main.class, "Min2Print6",
|
MethodType.methodType(
|
int.class, int.class, int.class, int.class, int.class, int.class, int.class));
|
assertEquals((int) mh.invokeExact(33, -4, 77, 88, 99, 111), 33);
|
try {
|
// Too few arguments
|
assertEquals((int) mh.invokeExact(33, -4, 77, 88), 33);
|
fail("No WMTE for too few arguments");
|
} catch (WrongMethodTypeException e) {}
|
try {
|
// Too many arguments
|
assertEquals((int) mh.invokeExact(33, -4, 77, 88, 89, 90, 91), 33);
|
fail("No WMTE for too many arguments");
|
} catch (WrongMethodTypeException e) {}
|
assertEquals((int) mh.invokeExact(-4, 77, 88, 99, 111, 33), 77);
|
assertEquals((int) mh.invokeExact(77, 88, 99, 111, 33, -4), 88);
|
assertEquals((int) mh.invokeExact(88, 99, 111, 33, -4, 77), 99);
|
assertEquals((int) mh.invokeExact(99, 111, 33, -4, 77, 88), 111);
|
assertEquals((int) mh.invokeExact(111, 33, -4, 77, 88, 99), 111);
|
|
// A preposterous number of arguments.
|
mh = MethodHandles.lookup().findStatic(
|
Main.class, "Min2Print26",
|
MethodType.methodType(
|
// Return-type
|
int.class,
|
// Arguments
|
int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
|
int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
|
int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
|
int.class, int.class));
|
assertEquals(1, (int) mh.invokeExact(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25));
|
assertEquals(25, (int) mh.invokeExact(25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24));
|
assertEquals(25, (int) mh.invokeExact(24, 25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23));
|
|
try {
|
// Wrong argument type
|
mh.invokeExact("a");
|
fail("No WMTE for wrong arguments");
|
} catch (WrongMethodTypeException wmte) {}
|
|
try {
|
// Invoke on null handle.
|
MethodHandle mh0 = null;
|
mh0.invokeExact("bad");
|
fail("No NPE for you");
|
} catch (NullPointerException npe) {}
|
|
System.out.println("BasicTest done.");
|
}
|
|
private static boolean And(boolean lhs, boolean rhs) {
|
return lhs & rhs;
|
}
|
|
private static boolean Xor(boolean lhs, boolean rhs) {
|
return lhs ^ rhs;
|
}
|
|
private static String Multiply(String value, int n) {
|
String result = "";
|
for (int i = 0; i < n; ++i) {
|
result = value + result;
|
}
|
return result;
|
}
|
|
private static byte Multiply(byte value, byte n) {
|
return (byte)(value * n);
|
}
|
|
private static short Multiply(short value, short n) {
|
return (short)(value * n);
|
}
|
|
private static int Multiply(int value, int n) {
|
return value * n;
|
}
|
|
private static long Multiply(long value, long n) {
|
return value * n;
|
}
|
|
private static float Multiply(float value, float n) {
|
return value * n;
|
}
|
|
private static double Multiply(double value, double n) {
|
return value * n;
|
}
|
|
private static char Next(char c) {
|
return (char)(c + 1);
|
}
|
|
public static void $opt$ReturnBooleanTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh =
|
lookup.findStatic(Main.class, "And",
|
MethodType.methodType(boolean.class, boolean.class, boolean.class));
|
assertEquals(true, (boolean) mh.invokeExact(true, true));
|
assertEquals(false, (boolean) mh.invokeExact(true, false));
|
assertEquals(false, (boolean) mh.invokeExact(false, true));
|
assertEquals(false, (boolean) mh.invokeExact(false, false));
|
assertEquals(true, (boolean) mh.invoke(true, true));
|
assertEquals(false, (boolean) mh.invoke(true, false));
|
assertEquals(false, (boolean) mh.invoke(false, true));
|
assertEquals(false, (boolean) mh.invoke(false, false));
|
|
mh = lookup.findStatic(Main.class, "Xor",
|
MethodType.methodType(boolean.class, boolean.class, boolean.class));
|
assertEquals(false, (boolean) mh.invokeExact(true, true));
|
assertEquals(true, (boolean) mh.invokeExact(true, false));
|
assertEquals(true, (boolean) mh.invokeExact(false, true));
|
assertEquals(false, (boolean) mh.invokeExact(false, false));
|
assertEquals(false, (boolean) mh.invoke(true, true));
|
assertEquals(true, (boolean) mh.invoke(true, false));
|
assertEquals(true, (boolean) mh.invoke(false, true));
|
assertEquals(false, (boolean) mh.invoke(false, false));
|
|
System.out.println("$opt$ReturnBooleanTest done.");
|
}
|
|
public static void $opt$ReturnCharTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh = lookup.findStatic(Main.class, "Next",
|
MethodType.methodType(char.class, char.class));
|
assertEquals('B', (char) mh.invokeExact('A'));
|
assertEquals((char) -55, (char) mh.invokeExact((char) -56));
|
System.out.println("$opt$ReturnCharTest done.");
|
}
|
|
public static void $opt$ReturnByteTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
|
MethodType.methodType(byte.class, byte.class, byte.class));
|
assertEquals((byte) 30, (byte) mh.invokeExact((byte) 10, (byte) 3));
|
assertEquals((byte) -90, (byte) mh.invoke((byte) -10, (byte) 9));
|
System.out.println("$opt$ReturnByteTest done.");
|
}
|
|
public static void $opt$ReturnShortTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
|
MethodType.methodType(short.class, short.class, short.class));
|
assertEquals((short) 3000, (short) mh.invokeExact((short) 1000, (short) 3));
|
assertEquals((short) -3000, (short) mh.invoke((short) -1000, (short) 3));
|
System.out.println("$opt$ReturnShortTest done.");
|
}
|
|
public static void $opt$ReturnIntTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
|
MethodType.methodType(int.class, int.class, int.class));
|
assertEquals(3_000_000, (int) mh.invokeExact(1_000_000, 3));
|
assertEquals(-3_000_000, (int) mh.invoke(-1_000, 3_000));
|
System.out.println("$opt$ReturnIntTest done.");
|
}
|
|
public static void $opt$ReturnLongTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
|
MethodType.methodType(long.class, long.class, long.class));
|
assertEquals(4_294_967_295_000L, (long) mh.invokeExact(1000L, 4_294_967_295L));
|
assertEquals(-4_294_967_295_000L, (long) mh.invoke(-1000L, 4_294_967_295L));
|
System.out.println("$opt$ReturnLongTest done.");
|
}
|
|
public static void $opt$ReturnFloatTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
|
MethodType.methodType(float.class, float.class, float.class));
|
assertEquals(3.0F, (float) mh.invokeExact(1000.0F, 3e-3F));
|
assertEquals(-3.0F, (float) mh.invoke(-1000.0F, 3e-3F));
|
System.out.println("$opt$ReturnFloatTest done.");
|
}
|
|
public static void $opt$ReturnDoubleTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
|
MethodType.methodType(double.class, double.class, double.class));
|
assertEquals(3033000.0, (double) mh.invokeExact(1000.0, 3.033e3));
|
assertEquals(-3033000.0, (double) mh.invoke(-1000.0, 3.033e3));
|
System.out.println("$opt$ReturnDoubleTest done.");
|
}
|
|
public static void $opt$ReturnStringTest() throws Throwable {
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
|
MethodType.methodType(String.class, String.class, int.class));
|
assertEquals("100010001000", (String) mh.invokeExact("1000", 3));
|
assertEquals("100010001000", (String) mh.invoke("1000", 3));
|
System.out.println("$opt$ReturnStringTest done.");
|
}
|
|
public static void ReturnValuesTest() throws Throwable {
|
$opt$ReturnBooleanTest();
|
$opt$ReturnCharTest();
|
$opt$ReturnByteTest();
|
$opt$ReturnShortTest();
|
$opt$ReturnIntTest();
|
$opt$ReturnLongTest();
|
$opt$ReturnFloatTest();
|
$opt$ReturnDoubleTest();
|
$opt$ReturnStringTest();
|
System.out.println("ReturnValuesTest done.");
|
}
|
|
static class ValueHolder {
|
public boolean m_z;
|
public static boolean s_z;
|
}
|
|
public static void $opt$AccessorsTest() throws Throwable {
|
ValueHolder valueHolder = new ValueHolder();
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
|
MethodHandle setMember = lookup.findSetter(ValueHolder.class, "m_z", boolean.class);
|
MethodHandle getMember = lookup.findGetter(ValueHolder.class, "m_z", boolean.class);
|
MethodHandle setStatic = lookup.findStaticSetter(ValueHolder.class, "s_z", boolean.class);
|
MethodHandle getStatic = lookup.findStaticGetter(ValueHolder.class, "s_z", boolean.class);
|
|
boolean [] values = { false, true, false, true, false };
|
for (boolean value : values) {
|
assertEquals((boolean) getStatic.invoke(), ValueHolder.s_z);
|
setStatic.invoke(value);
|
ValueHolder.s_z = value;
|
assertEquals(ValueHolder.s_z, value);
|
assertEquals((boolean) getStatic.invoke(), value);
|
|
assertEquals((boolean) getMember.invoke(valueHolder), valueHolder.m_z);
|
setMember.invoke(valueHolder, value);
|
valueHolder.m_z = value;
|
assertEquals(valueHolder.m_z, value);
|
assertEquals((boolean) getMember.invoke(valueHolder), value);
|
}
|
}
|
|
public static void main(String[] args) throws Throwable {
|
$opt$BasicTest();
|
ReturnValuesTest();
|
$opt$AccessorsTest();
|
}
|
}
|