blob: ce3f4db5d4ce68b10fc57f96181afdecf216b155 [file] [log] [blame]
Orion Hodsonac141392017-01-13 11:53:47 +00001/*
2 * Copyright (C) 2016 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
17import java.lang.invoke.MethodHandle;
18import java.lang.invoke.MethodHandles;
19import java.lang.invoke.MethodHandles.Lookup;
20import java.lang.invoke.MethodType;
21import java.lang.invoke.WrongMethodTypeException;
22import java.lang.reflect.Constructor;
23import java.lang.reflect.Field;
24import java.lang.reflect.Method;
25import java.nio.charset.Charset;
26import java.nio.charset.StandardCharsets;
27import java.util.ArrayList;
28import java.util.Arrays;
29import java.util.List;
30
31public class Main {
32 public static void assertTrue(boolean value) {
33 if (!value) {
34 throw new AssertionError("assertTrue value: " + value);
35 }
36 }
37
38 public static void assertFalse(boolean value) {
39 if (value) {
40 throw new AssertionError("assertTrue value: " + value);
41 }
42 }
43
44 public static void assertEquals(int i1, int i2) {
45 if (i1 == i2) { return; }
46 throw new AssertionError("assertEquals i1: " + i1 + ", i2: " + i2);
47 }
48
49 public static void assertEquals(long i1, long i2) {
50 if (i1 == i2) { return; }
51 throw new AssertionError("assertEquals l1: " + i1 + ", l2: " + i2);
52 }
53
54 public static void assertEquals(Object o, Object p) {
55 if (o == p) { return; }
56 if (o != null && p != null && o.equals(p)) { return; }
57 throw new AssertionError("assertEquals: o1: " + o + ", o2: " + p);
58 }
59
60 public static void assertEquals(String s1, String s2) {
61 if (s1 == s2) {
62 return;
63 }
64
65 if (s1 != null && s2 != null && s1.equals(s2)) {
66 return;
67 }
68
69 throw new AssertionError("assertEquals s1: " + s1 + ", s2: " + s2);
70 }
71
72 public static void fail() {
Kevin Brodskyf6c66c32015-12-17 14:13:00 +000073 System.out.println("fail");
Orion Hodsonac141392017-01-13 11:53:47 +000074 Thread.dumpStack();
75 }
76
77 public static void fail(String message) {
Kevin Brodskyf6c66c32015-12-17 14:13:00 +000078 System.out.println("fail: " + message);
Orion Hodsonac141392017-01-13 11:53:47 +000079 Thread.dumpStack();
80 }
81
82 public static int Min2Print2(int a, int b) {
83 int[] values = new int[] { a, b };
Kevin Brodskyf6c66c32015-12-17 14:13:00 +000084 System.out.println("Running Main.Min2Print2(" + Arrays.toString(values) + ")");
Orion Hodsonac141392017-01-13 11:53:47 +000085 return a > b ? a : b;
86 }
87
88 public static int Min2Print3(int a, int b, int c) {
89 int[] values = new int[] { a, b, c };
Kevin Brodskyf6c66c32015-12-17 14:13:00 +000090 System.out.println("Running Main.Min2Print3(" + Arrays.toString(values) + ")");
Orion Hodsonac141392017-01-13 11:53:47 +000091 return a > b ? a : b;
92 }
93
94 public static int Min2Print6(int a, int b, int c, int d, int e, int f) {
95 int[] values = new int[] { a, b, c, d, e, f };
Kevin Brodskyf6c66c32015-12-17 14:13:00 +000096 System.out.println("Running Main.Min2Print6(" + Arrays.toString(values) + ")");
Orion Hodsonac141392017-01-13 11:53:47 +000097 return a > b ? a : b;
98 }
99
100 public static int Min2Print26(int a, int b, int c, int d,
101 int e, int f, int g, int h,
102 int i, int j, int k, int l,
103 int m, int n, int o, int p,
104 int q, int r, int s, int t,
105 int u, int v, int w, int x,
106 int y, int z) {
107 int[] values = new int[] { a, b, c, d, e, f, g, h, i, j, k, l, m,
108 n, o, p, q, r, s, t, u, v, w, x, y, z };
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000109 System.out.println("Running Main.Min2Print26(" + Arrays.toString(values) + ")");
Orion Hodsonac141392017-01-13 11:53:47 +0000110 return a > b ? a : b;
111 }
112
113 public static void $opt$BasicTest() throws Throwable {
114 MethodHandle mh;
115 mh = MethodHandles.lookup().findStatic(
116 Main.class, "Min2Print2", MethodType.methodType(int.class, int.class, int.class));
117 assertEquals((int) mh.invokeExact(33, -4), 33);
118 assertEquals((int) mh.invokeExact(-4, 33), 33);
119
120 mh = MethodHandles.lookup().findStatic(
121 Main.class, "Min2Print3",
122 MethodType.methodType(int.class, int.class, int.class, int.class));
123 assertEquals((int) mh.invokeExact(33, -4, 17), 33);
124 assertEquals((int) mh.invokeExact(-4, 17, 33), 17);
125 assertEquals((int) mh.invokeExact(17, 33, -4), 33);
126
127 mh = MethodHandles.lookup().findStatic(
128 Main.class, "Min2Print6",
129 MethodType.methodType(
130 int.class, int.class, int.class, int.class, int.class, int.class, int.class));
131 assertEquals((int) mh.invokeExact(33, -4, 77, 88, 99, 111), 33);
132 try {
133 // Too few arguments
134 assertEquals((int) mh.invokeExact(33, -4, 77, 88), 33);
135 fail("No WMTE for too few arguments");
136 } catch (WrongMethodTypeException e) {}
137 try {
138 // Too many arguments
139 assertEquals((int) mh.invokeExact(33, -4, 77, 88, 89, 90, 91), 33);
140 fail("No WMTE for too many arguments");
141 } catch (WrongMethodTypeException e) {}
142 assertEquals((int) mh.invokeExact(-4, 77, 88, 99, 111, 33), 77);
143 assertEquals((int) mh.invokeExact(77, 88, 99, 111, 33, -4), 88);
144 assertEquals((int) mh.invokeExact(88, 99, 111, 33, -4, 77), 99);
145 assertEquals((int) mh.invokeExact(99, 111, 33, -4, 77, 88), 111);
146 assertEquals((int) mh.invokeExact(111, 33, -4, 77, 88, 99), 111);
147
148 // A preposterous number of arguments.
149 mh = MethodHandles.lookup().findStatic(
150 Main.class, "Min2Print26",
151 MethodType.methodType(
152 // Return-type
153 int.class,
154 // Arguments
155 int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
156 int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
157 int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
158 int.class, int.class));
159 assertEquals(1, (int) mh.invokeExact(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
160 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25));
161 assertEquals(25, (int) mh.invokeExact(25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
162 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24));
163 assertEquals(25, (int) mh.invokeExact(24, 25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
164 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23));
165
166 try {
167 // Wrong argument type
168 mh.invokeExact("a");
169 fail("No WMTE for wrong arguments");
170 } catch (WrongMethodTypeException wmte) {}
171
172 try {
173 // Invoke on null handle.
174 MethodHandle mh0 = null;
175 mh0.invokeExact("bad");
176 fail("No NPE for you");
177 } catch (NullPointerException npe) {}
178
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000179 System.out.println("BasicTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000180 }
181
182 private static boolean And(boolean lhs, boolean rhs) {
183 return lhs & rhs;
184 }
185
186 private static boolean Xor(boolean lhs, boolean rhs) {
187 return lhs ^ rhs;
188 }
189
190 private static String Multiply(String value, int n) {
191 String result = "";
192 for (int i = 0; i < n; ++i) {
193 result = value + result;
194 }
195 return result;
196 }
197
198 private static byte Multiply(byte value, byte n) {
199 return (byte)(value * n);
200 }
201
202 private static short Multiply(short value, short n) {
203 return (short)(value * n);
204 }
205
206 private static int Multiply(int value, int n) {
207 return value * n;
208 }
209
210 private static long Multiply(long value, long n) {
211 return value * n;
212 }
213
214 private static float Multiply(float value, float n) {
215 return value * n;
216 }
217
218 private static double Multiply(double value, double n) {
219 return value * n;
220 }
221
222 private static char Next(char c) {
223 return (char)(c + 1);
224 }
225
226 public static void $opt$ReturnBooleanTest() throws Throwable {
227 MethodHandles.Lookup lookup = MethodHandles.lookup();
228 MethodHandle mh =
229 lookup.findStatic(Main.class, "And",
230 MethodType.methodType(boolean.class, boolean.class, boolean.class));
231 assertEquals(true, (boolean) mh.invokeExact(true, true));
232 assertEquals(false, (boolean) mh.invokeExact(true, false));
233 assertEquals(false, (boolean) mh.invokeExact(false, true));
234 assertEquals(false, (boolean) mh.invokeExact(false, false));
235 assertEquals(true, (boolean) mh.invoke(true, true));
236 assertEquals(false, (boolean) mh.invoke(true, false));
237 assertEquals(false, (boolean) mh.invoke(false, true));
238 assertEquals(false, (boolean) mh.invoke(false, false));
239
240 mh = lookup.findStatic(Main.class, "Xor",
241 MethodType.methodType(boolean.class, boolean.class, boolean.class));
242 assertEquals(false, (boolean) mh.invokeExact(true, true));
243 assertEquals(true, (boolean) mh.invokeExact(true, false));
244 assertEquals(true, (boolean) mh.invokeExact(false, true));
245 assertEquals(false, (boolean) mh.invokeExact(false, false));
246 assertEquals(false, (boolean) mh.invoke(true, true));
247 assertEquals(true, (boolean) mh.invoke(true, false));
248 assertEquals(true, (boolean) mh.invoke(false, true));
249 assertEquals(false, (boolean) mh.invoke(false, false));
250
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000251 System.out.println("$opt$ReturnBooleanTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000252 }
253
254 public static void $opt$ReturnCharTest() throws Throwable {
255 MethodHandles.Lookup lookup = MethodHandles.lookup();
256 MethodHandle mh = lookup.findStatic(Main.class, "Next",
257 MethodType.methodType(char.class, char.class));
258 assertEquals('B', (char) mh.invokeExact('A'));
259 assertEquals((char) -55, (char) mh.invokeExact((char) -56));
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000260 System.out.println("$opt$ReturnCharTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000261 }
262
263 public static void $opt$ReturnByteTest() throws Throwable {
264 MethodHandles.Lookup lookup = MethodHandles.lookup();
265 MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
266 MethodType.methodType(byte.class, byte.class, byte.class));
267 assertEquals((byte) 30, (byte) mh.invokeExact((byte) 10, (byte) 3));
268 assertEquals((byte) -90, (byte) mh.invoke((byte) -10, (byte) 9));
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000269 System.out.println("$opt$ReturnByteTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000270 }
271
272 public static void $opt$ReturnShortTest() throws Throwable {
273 MethodHandles.Lookup lookup = MethodHandles.lookup();
274 MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
275 MethodType.methodType(short.class, short.class, short.class));
276 assertEquals((short) 3000, (short) mh.invokeExact((short) 1000, (short) 3));
277 assertEquals((short) -3000, (short) mh.invoke((short) -1000, (short) 3));
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000278 System.out.println("$opt$ReturnShortTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000279 }
280
281 public static void $opt$ReturnIntTest() throws Throwable {
282 MethodHandles.Lookup lookup = MethodHandles.lookup();
283 MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
284 MethodType.methodType(int.class, int.class, int.class));
285 assertEquals(3_000_000, (int) mh.invokeExact(1_000_000, 3));
286 assertEquals(-3_000_000, (int) mh.invoke(-1_000, 3_000));
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000287 System.out.println("$opt$ReturnIntTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000288 }
289
290 public static void $opt$ReturnLongTest() throws Throwable {
291 MethodHandles.Lookup lookup = MethodHandles.lookup();
292 MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
293 MethodType.methodType(long.class, long.class, long.class));
294 assertEquals(4_294_967_295_000L, (long) mh.invokeExact(1000L, 4_294_967_295L));
295 assertEquals(-4_294_967_295_000L, (long) mh.invoke(-1000L, 4_294_967_295L));
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000296 System.out.println("$opt$ReturnLongTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000297 }
298
299 public static void $opt$ReturnFloatTest() throws Throwable {
300 MethodHandles.Lookup lookup = MethodHandles.lookup();
301 MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
302 MethodType.methodType(float.class, float.class, float.class));
303 assertEquals(3.0F, (float) mh.invokeExact(1000.0F, 3e-3F));
304 assertEquals(-3.0F, (float) mh.invoke(-1000.0F, 3e-3F));
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000305 System.out.println("$opt$ReturnFloatTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000306 }
307
308 public static void $opt$ReturnDoubleTest() throws Throwable {
309 MethodHandles.Lookup lookup = MethodHandles.lookup();
310 MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
311 MethodType.methodType(double.class, double.class, double.class));
312 assertEquals(3033000.0, (double) mh.invokeExact(1000.0, 3.033e3));
313 assertEquals(-3033000.0, (double) mh.invoke(-1000.0, 3.033e3));
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000314 System.out.println("$opt$ReturnDoubleTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000315 }
316
317 public static void $opt$ReturnStringTest() throws Throwable {
318 MethodHandles.Lookup lookup = MethodHandles.lookup();
319 MethodHandle mh = lookup.findStatic(Main.class, "Multiply",
320 MethodType.methodType(String.class, String.class, int.class));
321 assertEquals("100010001000", (String) mh.invokeExact("1000", 3));
322 assertEquals("100010001000", (String) mh.invoke("1000", 3));
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000323 System.out.println("$opt$ReturnStringTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000324 }
325
326 public static void ReturnValuesTest() throws Throwable {
327 $opt$ReturnBooleanTest();
328 $opt$ReturnCharTest();
329 $opt$ReturnByteTest();
330 $opt$ReturnShortTest();
331 $opt$ReturnIntTest();
332 $opt$ReturnLongTest();
333 $opt$ReturnFloatTest();
334 $opt$ReturnDoubleTest();
335 $opt$ReturnStringTest();
Kevin Brodskyf6c66c32015-12-17 14:13:00 +0000336 System.out.println("ReturnValuesTest done.");
Orion Hodsonac141392017-01-13 11:53:47 +0000337 }
338
339 static class ValueHolder {
340 public boolean m_z;
341 public static boolean s_z;
342 }
343
344 public static void $opt$AccessorsTest() throws Throwable {
345 ValueHolder valueHolder = new ValueHolder();
346 MethodHandles.Lookup lookup = MethodHandles.lookup();
347
348 MethodHandle setMember = lookup.findSetter(ValueHolder.class, "m_z", boolean.class);
349 MethodHandle getMember = lookup.findGetter(ValueHolder.class, "m_z", boolean.class);
350 MethodHandle setStatic = lookup.findStaticSetter(ValueHolder.class, "s_z", boolean.class);
351 MethodHandle getStatic = lookup.findStaticGetter(ValueHolder.class, "s_z", boolean.class);
352
353 boolean [] values = { false, true, false, true, false };
354 for (boolean value : values) {
355 assertEquals((boolean) getStatic.invoke(), ValueHolder.s_z);
356 setStatic.invoke(value);
357 ValueHolder.s_z = value;
358 assertEquals(ValueHolder.s_z, value);
359 assertEquals((boolean) getStatic.invoke(), value);
360
361 assertEquals((boolean) getMember.invoke(valueHolder), valueHolder.m_z);
362 setMember.invoke(valueHolder, value);
363 valueHolder.m_z = value;
364 assertEquals(valueHolder.m_z, value);
365 assertEquals((boolean) getMember.invoke(valueHolder), value);
366 }
367 }
368
369 public static void main(String[] args) throws Throwable {
370 $opt$BasicTest();
371 ReturnValuesTest();
372 $opt$AccessorsTest();
373 }
374}