Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/invoke/InvokeGenericTest.java
41149 views
1
/*
2
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/* @test
25
* @summary unit tests for java.lang.invoke.MethodHandle.invoke
26
* @compile InvokeGenericTest.java
27
* @run testng/othervm test.java.lang.invoke.InvokeGenericTest
28
*/
29
30
package test.java.lang.invoke;
31
32
import java.lang.invoke.*;
33
import static java.lang.invoke.MethodHandles.*;
34
import static java.lang.invoke.MethodType.*;
35
import java.lang.reflect.*;
36
import java.util.*;
37
import org.testng.*;
38
import static org.testng.AssertJUnit.*;
39
import org.testng.annotations.*;
40
41
/**
42
*
43
* @author jrose
44
*/
45
@SuppressWarnings("cast") // various casts help emphasize arguments to invokeExact
46
public class InvokeGenericTest {
47
// How much output?
48
static int verbosity = 0;
49
static {
50
String vstr = System.getProperty("test.java.lang.invoke.InvokeGenericTest.verbosity");
51
if (vstr != null) verbosity = Integer.parseInt(vstr);
52
}
53
54
// public static void main(String... av) throws Throwable {
55
// new InvokeGenericTest().testFirst();
56
// }
57
58
@Test
59
public void testFirst() throws Throwable {
60
verbosity += 9; try {
61
// left blank for debugging
62
} finally { printCounts(); verbosity -= 9; }
63
}
64
65
public InvokeGenericTest() {
66
}
67
68
String testName;
69
static int allPosTests, allNegTests;
70
int posTests, negTests;
71
@AfterMethod
72
public void printCounts() {
73
if (verbosity >= 2 && (posTests | negTests) != 0) {
74
System.out.println();
75
if (posTests != 0) System.out.println("=== "+testName+": "+posTests+" positive test cases run");
76
if (negTests != 0) System.out.println("=== "+testName+": "+negTests+" negative test cases run");
77
allPosTests += posTests;
78
allNegTests += negTests;
79
posTests = negTests = 0;
80
}
81
}
82
void countTest(boolean positive) {
83
if (positive) ++posTests;
84
else ++negTests;
85
}
86
void countTest() { countTest(true); }
87
void startTest(String name) {
88
if (testName != null) printCounts();
89
if (verbosity >= 1)
90
System.out.println("["+name+"]");
91
posTests = negTests = 0;
92
testName = name;
93
}
94
95
@BeforeClass
96
public static void setUpClass() throws Exception {
97
calledLog.clear();
98
calledLog.add(null);
99
nextArgVal = INITIAL_ARG_VAL;
100
}
101
102
@AfterClass
103
public static void tearDownClass() throws Exception {
104
int posTests = allPosTests, negTests = allNegTests;
105
if (verbosity >= 2 && (posTests | negTests) != 0) {
106
System.out.println();
107
if (posTests != 0) System.out.println("=== "+posTests+" total positive test cases");
108
if (negTests != 0) System.out.println("=== "+negTests+" total negative test cases");
109
}
110
}
111
112
static List<Object> calledLog = new ArrayList<>();
113
static Object logEntry(String name, Object... args) {
114
return Arrays.asList(name, Arrays.asList(args));
115
}
116
static Object called(String name, Object... args) {
117
Object entry = logEntry(name, args);
118
calledLog.add(entry);
119
return entry;
120
}
121
static void assertCalled(String name, Object... args) {
122
Object expected = logEntry(name, args);
123
Object actual = calledLog.get(calledLog.size() - 1);
124
if (expected.equals(actual) && verbosity < 9) return;
125
System.out.println("assertCalled "+name+":");
126
System.out.println("expected: "+expected);
127
System.out.println("actual: "+actual);
128
System.out.println("ex. types: "+getClasses(expected));
129
System.out.println("act. types: "+getClasses(actual));
130
assertEquals("previous method call", expected, actual);
131
}
132
static void printCalled(MethodHandle target, String name, Object... args) {
133
if (verbosity >= 3)
134
System.out.println("calling MH="+target+" to "+name+Arrays.toString(args));
135
}
136
137
static Object castToWrapper(Object value, Class<?> dst) {
138
Object wrap = null;
139
if (value instanceof Number)
140
wrap = castToWrapperOrNull(((Number)value).longValue(), dst);
141
if (value instanceof Character)
142
wrap = castToWrapperOrNull((char)(Character)value, dst);
143
if (wrap != null) return wrap;
144
return dst.cast(value);
145
}
146
147
static Object castToWrapperOrNull(long value, Class<?> dst) {
148
if (dst == int.class || dst == Integer.class)
149
return (int)(value);
150
if (dst == long.class || dst == Long.class)
151
return (long)(value);
152
if (dst == char.class || dst == Character.class)
153
return (char)(value);
154
if (dst == short.class || dst == Short.class)
155
return (short)(value);
156
if (dst == float.class || dst == Float.class)
157
return (float)(value);
158
if (dst == double.class || dst == Double.class)
159
return (double)(value);
160
if (dst == byte.class || dst == Byte.class)
161
return (byte)(value);
162
if (dst == boolean.class || dst == boolean.class)
163
return ((value % 29) & 1) == 0;
164
return null;
165
}
166
167
static final int ONE_MILLION = (1000*1000), // first int value
168
TEN_BILLION = (10*1000*1000*1000), // scale factor to reach upper 32 bits
169
INITIAL_ARG_VAL = ONE_MILLION << 1; // <<1 makes space for sign bit;
170
static long nextArgVal;
171
static long nextArg(boolean moreBits) {
172
long val = nextArgVal++;
173
long sign = -(val & 1); // alternate signs
174
val >>= 1;
175
if (moreBits)
176
// Guarantee some bits in the high word.
177
// In any case keep the decimal representation simple-looking,
178
// with lots of zeroes, so as not to make the printed decimal
179
// strings unnecessarily noisy.
180
val += (val % ONE_MILLION) * TEN_BILLION;
181
return val ^ sign;
182
}
183
static int nextArg() {
184
// Produce a 32-bit result something like ONE_MILLION+(smallint).
185
// Example: 1_000_042.
186
return (int) nextArg(false);
187
}
188
static long nextArg(Class<?> kind) {
189
if (kind == long.class || kind == Long.class ||
190
kind == double.class || kind == Double.class)
191
// produce a 64-bit result something like
192
// ((TEN_BILLION+1) * (ONE_MILLION+(smallint)))
193
// Example: 10_000_420_001_000_042.
194
return nextArg(true);
195
return (long) nextArg();
196
}
197
198
static Object randomArg(Class<?> param) {
199
Object wrap = castToWrapperOrNull(nextArg(param), param);
200
if (wrap != null) {
201
return wrap;
202
}
203
// import sun.invoke.util.Wrapper;
204
// Wrapper wrap = Wrapper.forBasicType(dst);
205
// if (wrap == Wrapper.OBJECT && Wrapper.isWrapperType(dst))
206
// wrap = Wrapper.forWrapperType(dst);
207
// if (wrap != Wrapper.OBJECT)
208
// return wrap.wrap(nextArg++);
209
if (param.isInterface()) {
210
for (Class<?> c : param.getClasses()) {
211
if (param.isAssignableFrom(c) && !c.isInterface())
212
{ param = c; break; }
213
}
214
}
215
if (param.isInterface() || param.isAssignableFrom(String.class))
216
return "#"+nextArg();
217
else
218
try {
219
return param.newInstance();
220
} catch (InstantiationException | IllegalAccessException ex) {
221
}
222
return null; // random class not Object, String, Integer, etc.
223
}
224
static Object[] randomArgs(Class<?>... params) {
225
Object[] args = new Object[params.length];
226
for (int i = 0; i < args.length; i++)
227
args[i] = randomArg(params[i]);
228
return args;
229
}
230
static Object[] randomArgs(int nargs, Class<?> param) {
231
Object[] args = new Object[nargs];
232
for (int i = 0; i < args.length; i++)
233
args[i] = randomArg(param);
234
return args;
235
}
236
237
static final Object ANON_OBJ = new Object();
238
static Object zeroArg(Class<?> param) {
239
Object x = castToWrapperOrNull(0L, param);
240
if (x != null) return x;
241
if (param.isInterface() || param.isAssignableFrom(String.class)) return "\"\"";
242
if (param == Object.class) return ANON_OBJ;
243
if (param.getComponentType() != null) return Array.newInstance(param.getComponentType(), 0);
244
return null;
245
}
246
static Object[] zeroArgs(Class<?>... params) {
247
Object[] args = new Object[params.length];
248
for (int i = 0; i < args.length; i++)
249
args[i] = zeroArg(params[i]);
250
return args;
251
}
252
static Object[] zeroArgs(List<Class<?>> params) {
253
return zeroArgs(params.toArray(new Class<?>[0]));
254
}
255
256
@SafeVarargs @SuppressWarnings("varargs")
257
static <T, E extends T> T[] array(Class<T[]> atype, E... a) {
258
return Arrays.copyOf(a, a.length, atype);
259
}
260
@SafeVarargs @SuppressWarnings("varargs")
261
static <T> T[] cat(T[] a, T... b) {
262
int alen = a.length, blen = b.length;
263
if (blen == 0) return a;
264
T[] c = Arrays.copyOf(a, alen + blen);
265
System.arraycopy(b, 0, c, alen, blen);
266
return c;
267
}
268
static Integer[] boxAll(int... vx) {
269
Integer[] res = new Integer[vx.length];
270
for (int i = 0; i < res.length; i++) {
271
res[i] = vx[i];
272
}
273
return res;
274
}
275
static Object getClasses(Object x) {
276
if (x == null) return x;
277
if (x instanceof String) return x; // keep the name
278
if (x instanceof List) {
279
// recursively report classes of the list elements
280
Object[] xa = ((List)x).toArray();
281
for (int i = 0; i < xa.length; i++)
282
xa[i] = getClasses(xa[i]);
283
return Arrays.asList(xa);
284
}
285
return x.getClass().getSimpleName();
286
}
287
288
static MethodHandle changeArgTypes(MethodHandle target, Class<?> argType) {
289
return changeArgTypes(target, 0, 999, argType);
290
}
291
static MethodHandle changeArgTypes(MethodHandle target,
292
int beg, int end, Class<?> argType) {
293
MethodType targetType = target.type();
294
end = Math.min(end, targetType.parameterCount());
295
ArrayList<Class<?>> argTypes = new ArrayList<>(targetType.parameterList());
296
Collections.fill(argTypes.subList(beg, end), argType);
297
MethodType ttype2 = MethodType.methodType(targetType.returnType(), argTypes);
298
return target.asType(ttype2);
299
}
300
301
// This lookup is good for all members in and under InvokeGenericTest.
302
static final Lookup LOOKUP = MethodHandles.lookup();
303
304
Map<List<Class<?>>, MethodHandle> CALLABLES = new HashMap<>();
305
MethodHandle callable(List<Class<?>> params) {
306
MethodHandle mh = CALLABLES.get(params);
307
if (mh == null) {
308
mh = collector_MH.asType(methodType(Object.class, params));
309
CALLABLES.put(params, mh);
310
}
311
return mh;
312
}
313
MethodHandle callable(Class<?>... params) {
314
return callable(Arrays.asList(params));
315
}
316
private static Object collector(Object... args) {
317
return Arrays.asList(args);
318
}
319
private static final MethodHandle collector_MH;
320
static {
321
try {
322
collector_MH
323
= LOOKUP.findStatic(LOOKUP.lookupClass(),
324
"collector",
325
methodType(Object.class, Object[].class));
326
} catch (ReflectiveOperationException ex) {
327
throw new RuntimeException(ex);
328
}
329
}
330
331
@Test
332
public void testSimple() throws Throwable {
333
startTest("testSimple");
334
countTest();
335
String[] args = { "one", "two" };
336
MethodHandle mh = callable(Object.class, String.class);
337
Object res; List<?> resl;
338
res = resl = (List<?>) mh.invoke((String)args[0], (Object)args[1]);
339
//System.out.println(res);
340
assertEquals(Arrays.asList(args), res);
341
}
342
343
@Test
344
public void testSimplePrims() throws Throwable {
345
startTest("testSimplePrims");
346
countTest();
347
int[] args = { 1, 2 };
348
MethodHandle mh = callable(Object.class, Object.class);
349
Object res; List<?> resl;
350
res = resl = (List<?>) mh.invoke(args[0], args[1]);
351
//System.out.println(res);
352
assertEquals(Arrays.toString(args), res.toString());
353
}
354
355
@Test
356
public void testAlternateName() throws Throwable {
357
startTest("testAlternateName");
358
countTest();
359
String[] args = { "one", "two" };
360
MethodHandle mh = callable(Object.class, String.class);
361
Object res; List<?> resl;
362
res = resl = (List<?>) mh.invoke((String)args[0], (Object)args[1]);
363
//System.out.println(res);
364
assertEquals(Arrays.asList(args), res);
365
}
366
367
@Test
368
public void testWrongArgumentCount() throws Throwable {
369
startTest("testWrongArgumentCount");
370
for (int i = 0; i <= 10; i++) {
371
testWrongArgumentCount(Collections.<Class<?>>nCopies(i, Integer.class));
372
if (i <= 4) {
373
testWrongArgumentCount(Collections.<Class<?>>nCopies(i, int.class));
374
testWrongArgumentCount(Collections.<Class<?>>nCopies(i, long.class));
375
}
376
}
377
}
378
public void testWrongArgumentCount(List<Class<?>> params) throws Throwable {
379
int max = params.size();
380
for (int i = 0; i < max; i++) {
381
List<Class<?>> params2 = params.subList(0, i);
382
for (int k = 0; k <= 2; k++) {
383
if (k == 1) params = methodType(Object.class, params).generic().parameterList();
384
if (k == 2) params2 = methodType(Object.class, params2).generic().parameterList();
385
testWrongArgumentCount(params, params2);
386
testWrongArgumentCount(params2, params);
387
}
388
}
389
}
390
public void testWrongArgumentCount(List<Class<?>> expect, List<Class<?>> observe) throws Throwable {
391
countTest(false);
392
if (expect.equals(observe))
393
assert(false);
394
MethodHandle target = callable(expect);
395
Object[] args = zeroArgs(observe);
396
Object junk;
397
try {
398
switch (args.length) {
399
case 0:
400
junk = target.invoke(); break;
401
case 1:
402
junk = target.invoke(args[0]); break;
403
case 2:
404
junk = target.invoke(args[0], args[1]); break;
405
case 3:
406
junk = target.invoke(args[0], args[1], args[2]); break;
407
case 4:
408
junk = target.invoke(args[0], args[1], args[2], args[3]); break;
409
default:
410
junk = target.invokeWithArguments(args); break;
411
}
412
} catch (WrongMethodTypeException ex) {
413
return;
414
} catch (Exception ex) {
415
throw new RuntimeException("wrong exception calling "+target+" on "+Arrays.asList(args), ex);
416
}
417
throw new RuntimeException("bad success calling "+target+" on "+Arrays.asList(args));
418
}
419
420
/** Make a list of all combinations of the given types, with the given arities.
421
* A void return type is possible iff the first type is void.class.
422
*/
423
static List<MethodType> allMethodTypes(int minargc, int maxargc, Class<?>... types) {
424
ArrayList<MethodType> result = new ArrayList<>();
425
if (types.length > 0) {
426
ArrayList<MethodType> argcTypes = new ArrayList<>();
427
// build arity-zero types first
428
for (Class<?> rtype : types) {
429
argcTypes.add(MethodType.methodType(rtype));
430
}
431
if (types[0] == void.class)
432
// void is not an argument type
433
types = Arrays.copyOfRange(types, 1, types.length);
434
for (int argc = 0; argc <= maxargc; argc++) {
435
if (argc >= minargc)
436
result.addAll(argcTypes);
437
if (argc >= maxargc)
438
break;
439
ArrayList<MethodType> prevTypes = argcTypes;
440
argcTypes = new ArrayList<>();
441
for (MethodType prevType : prevTypes) {
442
for (Class<?> ptype : types) {
443
argcTypes.add(prevType.insertParameterTypes(argc, ptype));
444
}
445
}
446
}
447
}
448
return Collections.unmodifiableList(result);
449
}
450
static List<MethodType> allMethodTypes(int argc, Class<?>... types) {
451
return allMethodTypes(argc, argc, types);
452
}
453
454
MethodHandle toString_MH;
455
456
@Test
457
public void testReferenceConversions() throws Throwable {
458
startTest("testReferenceConversions");
459
toString_MH = LOOKUP.
460
findVirtual(Object.class, "toString", MethodType.methodType(String.class));
461
Object[] args = { "one", "two" };
462
for (MethodType type : allMethodTypes(2, Object.class, String.class, CharSequence.class)) {
463
testReferenceConversions(type, args);
464
}
465
}
466
public void testReferenceConversions(MethodType type, Object... args) throws Throwable {
467
countTest();
468
int nargs = args.length;
469
List<Object> argList = Arrays.asList(args);
470
String expectString = argList.toString();
471
if (verbosity > 3) System.out.println("target type: "+type+expectString);
472
MethodHandle mh = callable(type.parameterList());
473
mh = MethodHandles.filterReturnValue(mh, toString_MH);
474
mh = mh.asType(type);
475
Object res = null;
476
if (nargs == 2) {
477
res = mh.invoke((Object)args[0], (Object)args[1]);
478
assertEquals(expectString, res);
479
res = mh.invoke((String)args[0], (Object)args[1]);
480
assertEquals(expectString, res);
481
res = mh.invoke((Object)args[0], (String)args[1]);
482
assertEquals(expectString, res);
483
res = mh.invoke((String)args[0], (String)args[1]);
484
assertEquals(expectString, res);
485
res = mh.invoke((String)args[0], (CharSequence)args[1]);
486
assertEquals(expectString, res);
487
res = mh.invoke((CharSequence)args[0], (Object)args[1]);
488
assertEquals(expectString, res);
489
res = (String) mh.invoke((Object)args[0], (Object)args[1]);
490
assertEquals(expectString, res);
491
res = (String) mh.invoke((String)args[0], (Object)args[1]);
492
assertEquals(expectString, res);
493
res = (CharSequence) mh.invoke((String)args[0], (Object)args[1]);
494
assertEquals(expectString, res);
495
} else {
496
assert(false); // write this code
497
}
498
//System.out.println(res);
499
}
500
501
502
@Test
503
public void testBoxConversions() throws Throwable {
504
startTest("testBoxConversions");
505
countTest();
506
Object[] args = { 1, 2 };
507
MethodHandle mh = callable(Object.class, int.class);
508
Object res; List<?> resl; int resi;
509
res = resl = (List<?>) mh.invoke((int)args[0], (Object)args[1]);
510
//System.out.println(res);
511
assertEquals(Arrays.asList(args), res);
512
mh = MethodHandles.identity(int.class);
513
mh = MethodHandles.dropArguments(mh, 1, int.class);
514
res = resi = (int) mh.invoke((Object) args[0], (Object) args[1]);
515
assertEquals(args[0], res);
516
res = resi = (int) mh.invoke((int) args[0], (Object) args[1]);
517
assertEquals(args[0], res);
518
}
519
520
}
521
522