Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/invoke/ExplicitCastArgumentsTest.java
41149 views
1
/*
2
* Copyright (c) 2014, 2018, 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
import sun.invoke.util.Wrapper;
25
import test.java.lang.invoke.lib.Helper;
26
27
import java.io.File;
28
import java.io.Serializable;
29
import java.lang.invoke.MethodHandle;
30
import java.lang.invoke.MethodHandles;
31
import java.lang.invoke.MethodType;
32
import java.lang.invoke.WrongMethodTypeException;
33
import java.util.HashMap;
34
import java.util.Map;
35
import java.util.Random;
36
37
/*
38
* @test
39
* @bug 8060483 8066746
40
* @key randomness
41
* @library /test/lib /java/lang/invoke/common
42
* @modules java.base/sun.invoke.util
43
* @summary unit tests for MethodHandles.explicitCastArguments()
44
* @run main ExplicitCastArgumentsTest
45
*/
46
47
/**
48
* Tests for MethodHandles.explicitCastArguments().
49
*/
50
public class ExplicitCastArgumentsTest {
51
52
private static final boolean VERBOSE = Helper.IS_VERBOSE;
53
private static final Class<?> THIS_CLASS = ExplicitCastArgumentsTest.class;
54
private static final Random RNG = Helper.RNG;
55
private static final Map<Wrapper, Object> RANDOM_VALUES = new HashMap<>(9);
56
57
static {
58
RANDOM_VALUES.put(Wrapper.BOOLEAN, RNG.nextBoolean());
59
RANDOM_VALUES.put(Wrapper.BYTE, (byte) RNG.nextInt());
60
RANDOM_VALUES.put(Wrapper.SHORT, (short) RNG.nextInt());
61
RANDOM_VALUES.put(Wrapper.CHAR, (char) RNG.nextInt());
62
RANDOM_VALUES.put(Wrapper.INT, RNG.nextInt());
63
RANDOM_VALUES.put(Wrapper.LONG, RNG.nextLong());
64
RANDOM_VALUES.put(Wrapper.FLOAT, RNG.nextFloat());
65
RANDOM_VALUES.put(Wrapper.DOUBLE, RNG.nextDouble());
66
RANDOM_VALUES.put(Wrapper.OBJECT, new Object());
67
}
68
69
public static void main(String[] args) throws Throwable {
70
testVarargsCollector();
71
testNullRef2Prim();
72
testRef2Prim();
73
testPrim2Ref();
74
testPrim2Prim();
75
testNonBCPRef2NonBCPRef();
76
testBCPRef2BCPRef();
77
testNonBCPRef2BCPRef();
78
testReturnAny2Void();
79
testReturnVoid2Any();
80
testMultipleArgs();
81
System.out.println("TEST PASSED");
82
}
83
84
/**
85
* Dummy method used in {@link #testVarargsCollector} test to form a method
86
* handle.
87
*
88
* @param args - any args
89
* @return - returns args
90
*/
91
public static String[] f(String... args) {
92
return args;
93
}
94
95
/**
96
* Tests that MHs.explicitCastArguments does incorrect type checks for
97
* VarargsCollector. Bug 8066746.
98
*
99
* @throws java.lang.Throwable
100
*/
101
public static void testVarargsCollector() throws Throwable {
102
MethodType mt = MethodType.methodType(String[].class, String[].class);
103
MethodHandle mh = MethodHandles.publicLookup()
104
.findStatic(THIS_CLASS, "f", mt);
105
mh = MethodHandles.explicitCastArguments(mh,
106
MethodType.methodType(Object.class, Object.class));
107
mh.invokeWithArguments((Object) (new String[]{"str1", "str2"}));
108
}
109
110
/**
111
* Tests that null wrapper reference is successfully converted to primitive
112
* types. Converted result should be zero for a primitive. Bug 8060483.
113
*/
114
public static void testNullRef2Prim() {
115
for (Wrapper from : Wrapper.values()) {
116
for (Wrapper to : Wrapper.values()) {
117
if (from == Wrapper.VOID || to == Wrapper.VOID) {
118
continue;
119
}
120
// MHs.eCA javadoc:
121
// If T0 is a reference and T1 a primitive, and if the reference
122
// is null at runtime, a zero value is introduced.
123
for (TestConversionMode mode : TestConversionMode.values()) {
124
testConversion(mode, from.wrapperType(),
125
to.primitiveType(), null, to.zero(), false, null);
126
}
127
}
128
}
129
}
130
131
/**
132
* Tests that non-null wrapper reference is successfully converted to
133
* primitive types.
134
*/
135
public static void testRef2Prim() {
136
for (Wrapper from : Wrapper.values()) {
137
for (Wrapper to : Wrapper.values()) {
138
if (from == Wrapper.VOID || to == Wrapper.VOID
139
|| to == Wrapper.OBJECT) {
140
continue;
141
}
142
Object value = RANDOM_VALUES.get(from);
143
for (TestConversionMode mode : TestConversionMode.values()) {
144
if (from != Wrapper.OBJECT) {
145
Object convValue = to.wrap(value);
146
testConversion(mode, from.wrapperType(),
147
to.primitiveType(), value, convValue, false, null);
148
} else {
149
testConversion(mode, from.wrapperType(),
150
to.primitiveType(), value, null,
151
true, ClassCastException.class);
152
}
153
}
154
}
155
}
156
}
157
158
/**
159
* Tests that primitive is successfully converted to wrapper reference
160
* types, to the Number type (if possible) and to the Object type.
161
*/
162
public static void testPrim2Ref() {
163
for (Wrapper from : Wrapper.values()) {
164
for (Wrapper to : Wrapper.values()) {
165
if (from == Wrapper.VOID || from == Wrapper.OBJECT
166
|| to == Wrapper.VOID || to == Wrapper.OBJECT) {
167
continue;
168
}
169
Object value = RANDOM_VALUES.get(from);
170
for (TestConversionMode mode : TestConversionMode.values()) {
171
if (from == to) {
172
testConversion(mode, from.primitiveType(),
173
to.wrapperType(), value, value, false, null);
174
} else {
175
testConversion(mode, from.primitiveType(),
176
to.wrapperType(), value, null, true, ClassCastException.class);
177
}
178
if (from != Wrapper.BOOLEAN && from != Wrapper.CHAR) {
179
testConversion(mode, from.primitiveType(),
180
Number.class, value, value, false, null);
181
} else {
182
testConversion(mode, from.primitiveType(),
183
Number.class, value, null,
184
true, ClassCastException.class);
185
}
186
testConversion(mode, from.primitiveType(),
187
Object.class, value, value, false, null);
188
}
189
}
190
}
191
}
192
193
/**
194
* Tests that primitive is successfully converted to other primitive type.
195
*/
196
public static void testPrim2Prim() {
197
for (Wrapper from : Wrapper.values()) {
198
for (Wrapper to : Wrapper.values()) {
199
if (from == Wrapper.VOID || to == Wrapper.VOID
200
|| from == Wrapper.OBJECT || to == Wrapper.OBJECT) {
201
continue;
202
}
203
Object value = RANDOM_VALUES.get(from);
204
Object convValue = to.wrap(value);
205
for (TestConversionMode mode : TestConversionMode.values()) {
206
testConversion(mode, from.primitiveType(),
207
to.primitiveType(), value, convValue, false, null);
208
}
209
}
210
}
211
}
212
213
/**
214
* Dummy interface for {@link #testNonBCPRef2Ref} test.
215
*/
216
public static interface TestInterface {}
217
218
/**
219
* Dummy class for {@link #testNonBCPRef2Ref} test.
220
*/
221
public static class TestSuperClass implements TestInterface {}
222
223
/**
224
* Dummy class for {@link #testNonBCPRef2Ref} test.
225
*/
226
public static class TestSubClass1 extends TestSuperClass {}
227
228
/**
229
* Dummy class for {@link #testNonBCPRef2Ref} test.
230
*/
231
public static class TestSubClass2 extends TestSuperClass {}
232
233
/**
234
* Tests non-bootclasspath reference to reference conversions.
235
*
236
* @throws java.lang.Throwable
237
*/
238
public static void testNonBCPRef2NonBCPRef() throws Throwable {
239
Class testInterface = TestInterface.class;
240
Class testSuperClass = TestSuperClass.class;
241
Class testSubClass1 = TestSubClass1.class;
242
Class testSubClass2 = TestSubClass2.class;
243
Object testSuperObj = new TestSuperClass();
244
Object testObj01 = new TestSubClass1();
245
Object testObj02 = new TestSubClass2();
246
Class[] parents = {testInterface, testSuperClass};
247
Class[] children = {testSubClass1, testSubClass2};
248
Object[] childInst = {testObj01, testObj02};
249
for (TestConversionMode mode : TestConversionMode.values()) {
250
for (Class parent : parents) {
251
for (int j = 0; j < children.length; j++) {
252
// Child type to parent type non-null conversion, shoud succeed
253
testConversion(mode, children[j], parent, childInst[j],
254
childInst[j], false, null);
255
// Child type to parent type null conversion, shoud succeed
256
testConversion(mode, children[j], parent, null,
257
null, false, null);
258
// Parent type to child type non-null conversion with parent
259
// type instance, should fail
260
testConversion(mode, parent, children[j], testSuperObj,
261
null, true, ClassCastException.class);
262
// Parent type to child type non-null conversion with child
263
// type instance, should succeed
264
testConversion(mode, parent, children[j], childInst[j],
265
childInst[j], false, null);
266
// Parent type to child type null conversion, should succeed
267
testConversion(mode, parent, children[j], null,
268
null, false, null);
269
}
270
// Parent type to child type non-null conversion with sibling
271
// type instance, should fail
272
testConversion(mode, parent, testSubClass1, testObj02,
273
null, true, ClassCastException.class);
274
}
275
// Sibling type non-null conversion, should fail
276
testConversion(mode, testSubClass1,
277
testSubClass2, testObj01, null, true,
278
ClassCastException.class);
279
// Sibling type null conversion, should succeed
280
testConversion(mode, testSubClass1,
281
testSubClass2, null, null, false, null);
282
}
283
}
284
285
/**
286
* Dummy interface for {@link #testNonBCPRef2BCPRef} test.
287
*/
288
public static interface TestSerializableInterface extends Serializable {}
289
290
/**
291
* Dummy class for {@link #testNonBCPRef2BCPRef} test.
292
*/
293
public static class TestSerializableClass
294
implements TestSerializableInterface {}
295
296
/**
297
* Dummy class for {@link #testNonBCPRef2BCPRef} test.
298
*/
299
public static class TestFileChildClass extends File
300
implements TestSerializableInterface {
301
public TestFileChildClass(String pathname) {
302
super(pathname);
303
}
304
}
305
306
/**
307
* Tests non-bootclasspath reference to bootclasspath reference conversions
308
* and vice-versa.
309
*
310
* @throws java.lang.Throwable
311
*/
312
public static void testNonBCPRef2BCPRef() throws Throwable {
313
Class bcpInterface = Serializable.class;
314
Class bcpSuperClass = File.class;
315
Class nonBcpInterface = TestSerializableInterface.class;
316
Class nonBcpSuperSiblingClass = TestSerializableClass.class;
317
Class nonBcpSubClass = TestFileChildClass.class;
318
Object bcpSuperObj = new File(".");
319
Object testSuperSiblingObj = new TestSerializableClass();
320
Object testSubObj = new TestFileChildClass(".");
321
Class[] parents = {bcpInterface, bcpSuperClass};
322
for (TestConversionMode mode : TestConversionMode.values()) {
323
for (Class parent : parents) {
324
// Child type to parent type non-null conversion, shoud succeed
325
testConversion(mode, nonBcpSubClass, parent, testSubObj,
326
testSubObj, false, null);
327
// Child type to parent type null conversion, shoud succeed
328
testConversion(mode, nonBcpSubClass, parent, null, null,
329
false, null);
330
// Parent type to child type non-null conversion with parent
331
// type instance, should fail
332
testConversion(mode, parent, nonBcpSubClass, bcpSuperObj, null,
333
true, ClassCastException.class);
334
// Parent type to child type non-null conversion with child
335
// type instance, should succeed
336
testConversion(mode, parent, nonBcpSubClass, testSubObj,
337
testSubObj, false, null);
338
// Parent type to child type null conversion, should succeed
339
testConversion(mode, parent, nonBcpSubClass, null, null,
340
false, null);
341
}
342
// Parent type to child type non-null conversion with
343
// super sibling type instance, should fail
344
testConversion(mode, bcpInterface, nonBcpSubClass,
345
testSuperSiblingObj, null, true, ClassCastException.class);
346
Class[] siblings = {nonBcpSubClass, bcpSuperClass};
347
for (Class sibling : siblings) {
348
// Non-bcp class to bcp/non-bcp sibling class non-null
349
// conversion with nonBcpSuperSiblingClass instance, should fail
350
testConversion(mode, nonBcpSuperSiblingClass, sibling,
351
testSuperSiblingObj, null, true, ClassCastException.class);
352
// Non-bcp class to bcp/non-bcp sibling class null conversion,
353
// should succeed
354
testConversion(mode, nonBcpSuperSiblingClass, sibling,
355
null, null, false, null);
356
// Non-bcp interface to bcp/non-bcp sibling class non-null
357
// conversion with nonBcpSubClass instance, should succeed
358
testConversion(mode, nonBcpInterface, sibling, testSubObj,
359
testSubObj, false, null);
360
// Non-bcp interface to bcp/non-bcp sibling class
361
// null conversion, should succeed
362
testConversion(mode, nonBcpInterface, sibling, null, null,
363
false, null);
364
// Non-bcp interface to bcp/non-bcp sibling class non-null
365
// conversion with nonBcpSuperSiblingClass instance, should fail
366
testConversion(mode, nonBcpInterface, sibling,
367
testSuperSiblingObj, testSubObj,
368
true, ClassCastException.class);
369
}
370
}
371
}
372
373
/**
374
* Tests bootclasspath reference to reference conversions.
375
*/
376
public static void testBCPRef2BCPRef() {
377
Class bcpInterface = CharSequence.class;
378
Class bcpSubClass1 = String.class;
379
Class bcpSubClass2 = StringBuffer.class;
380
Object testObj01 = new String("test");
381
Object testObj02 = new StringBuffer("test");
382
Class[] children = {bcpSubClass1, bcpSubClass2};
383
Object[] childInst = {testObj01, testObj02};
384
for (TestConversionMode mode : TestConversionMode.values()) {
385
for (int i = 0; i < children.length; i++) {
386
// Child type to parent type non-null conversion, shoud succeed
387
testConversion(mode, children[i], bcpInterface, childInst[i],
388
childInst[i], false, null);
389
// Child type to parent type null conversion, shoud succeed
390
testConversion(mode, children[i], bcpInterface, null,
391
null, false, null);
392
// Parent type to child type non-null conversion with child
393
// type instance, should succeed
394
testConversion(mode, bcpInterface,
395
children[i], childInst[i], childInst[i], false, null);
396
// Parent type to child type null conversion, should succeed
397
testConversion(mode, bcpInterface,
398
children[i], null, null, false, null);
399
}
400
// Sibling type non-null conversion, should fail
401
testConversion(mode, bcpSubClass1,
402
bcpSubClass2, testObj01, null, true,
403
ClassCastException.class);
404
// Sibling type null conversion, should succeed
405
testConversion(mode, bcpSubClass1,
406
bcpSubClass2, null, null, false, null);
407
// Parent type to child type non-null conversion with sibling
408
// type instance, should fail
409
testConversion(mode, bcpInterface, bcpSubClass1, testObj02,
410
null, true, ClassCastException.class);
411
}
412
}
413
414
/**
415
* Dummy method used in {@link #testReturnAny2Void} and
416
* {@link #testReturnVoid2Any} tests to form a method handle.
417
*/
418
public static void retVoid() {}
419
420
/**
421
* Tests that non-null any return is successfully converted to non-type
422
* void.
423
*/
424
public static void testReturnAny2Void() {
425
for (Wrapper from : Wrapper.values()) {
426
testConversion(TestConversionMode.RETURN_VALUE, from.wrapperType(),
427
void.class, RANDOM_VALUES.get(from),
428
null, false, null);
429
testConversion(TestConversionMode.RETURN_VALUE, from.primitiveType(),
430
void.class, RANDOM_VALUES.get(from),
431
null, false, null);
432
}
433
}
434
435
/**
436
* Tests that void return is successfully converted to primitive and
437
* reference. Result should be zero for primitives and null for references.
438
*/
439
public static void testReturnVoid2Any() {
440
for (Wrapper to : Wrapper.values()) {
441
testConversion(TestConversionMode.RETURN_VALUE, void.class,
442
to.primitiveType(), null,
443
to.zero(), false, null);
444
testConversion(TestConversionMode.RETURN_VALUE, void.class,
445
to.wrapperType(), null,
446
null, false, null);
447
}
448
}
449
450
private static void checkForWrongMethodTypeException(MethodHandle mh, MethodType mt) {
451
try {
452
MethodHandles.explicitCastArguments(mh, mt);
453
throw new AssertionError("Expected WrongMethodTypeException is not thrown");
454
} catch (WrongMethodTypeException wmte) {
455
if (VERBOSE) {
456
System.out.printf("Expected exception %s: %s\n",
457
wmte.getClass(), wmte.getMessage());
458
}
459
}
460
}
461
462
/**
463
* Tests that MHs.eCA method works correctly with MHs with multiple arguments.
464
* @throws Throwable
465
*/
466
public static void testMultipleArgs() throws Throwable {
467
int arity = 1 + RNG.nextInt(Helper.MAX_ARITY / 2 - 2);
468
int arityMinus = RNG.nextInt(arity);
469
int arityPlus = arity + RNG.nextInt(Helper.MAX_ARITY / 2 - arity) + 1;
470
MethodType mType = Helper.randomMethodTypeGenerator(arity);
471
MethodType mTypeNew = Helper.randomMethodTypeGenerator(arity);
472
MethodType mTypeNewMinus = Helper.randomMethodTypeGenerator(arityMinus);
473
MethodType mTypeNewPlus = Helper.randomMethodTypeGenerator(arityPlus);
474
Class<?> rType = mType.returnType();
475
MethodHandle original;
476
if (rType.equals(void.class)) {
477
MethodType mt = MethodType.methodType(void.class);
478
original = MethodHandles.publicLookup()
479
.findStatic(THIS_CLASS, "retVoid", mt);
480
} else {
481
Object rValue = Helper.castToWrapper(1, rType);
482
original = MethodHandles.constant(rType, rValue);
483
}
484
original = Helper.addTrailingArgs(original, arity, mType.parameterList());
485
MethodHandle target = MethodHandles
486
.explicitCastArguments(original, mTypeNew);
487
Object[] parList = Helper.randomArgs(mTypeNew.parameterList());
488
for (int i = 0; i < parList.length; i++) {
489
if (parList[i] instanceof String) {
490
parList[i] = null; //getting rid of Stings produced by randomArgs
491
}
492
}
493
target.invokeWithArguments(parList);
494
checkForWrongMethodTypeException(original, mTypeNewMinus);
495
checkForWrongMethodTypeException(original, mTypeNewPlus);
496
}
497
498
/**
499
* Enumeration of test conversion modes.
500
*/
501
public enum TestConversionMode {
502
RETURN_VALUE,
503
ARGUMENT;
504
}
505
506
/**
507
* Tests type and value conversion. Comparing with the given expected result.
508
*
509
* @param mode - test conversion mode. See {@link #TestConversionMode}.
510
* @param from - source type.
511
* @param to - destination type.
512
* @param param - value to be converted.
513
* @param expectedResult - expected value after conversion.
514
* @param failureExpected - true if conversion failure expected.
515
* @param expectedException - expected exception class if
516
* {@code failureExpected} is true.
517
*/
518
public static void testConversion(TestConversionMode mode,
519
Class<?> from, Class<?> to, Object param,
520
Object expectedResult, boolean failureExpected,
521
Class<? extends Throwable> expectedException) {
522
if (VERBOSE) {
523
System.out.printf("Testing return value conversion: "
524
+ "%-10s => %-10s: %5s: ", from.getSimpleName(),
525
to.getSimpleName(), param);
526
}
527
MethodHandle original = null;
528
MethodType newType = null;
529
switch (mode) {
530
case RETURN_VALUE:
531
if (from.equals(void.class)) {
532
MethodType mt = MethodType.methodType(void.class);
533
try {
534
original = MethodHandles.publicLookup()
535
.findStatic(THIS_CLASS, "retVoid", mt);
536
} catch (NoSuchMethodException | IllegalAccessException ex) {
537
throw new Error("Unexpected issue", ex);
538
}
539
} else {
540
original = MethodHandles.constant(from, param);
541
}
542
newType = original.type().changeReturnType(to);
543
break;
544
case ARGUMENT:
545
if (from.equals(void.class) || to.equals(void.class)) {
546
throw new Error("Test issue: argument conversion does not"
547
+ " work with non-type void");
548
}
549
original = MethodHandles.identity(to);
550
newType = original.type().changeParameterType(0, from);
551
break;
552
default:
553
String msg = String.format("Test issue: unknown test"
554
+ " convertion mode %s.", mode.name());
555
throw new Error(msg);
556
}
557
try {
558
MethodHandle target = MethodHandles
559
.explicitCastArguments(original, newType);
560
Object result;
561
switch (mode) {
562
case RETURN_VALUE:
563
result = target.invokeWithArguments();
564
break;
565
case ARGUMENT:
566
result = target.invokeWithArguments(param);
567
break;
568
default:
569
String msg = String.format("Test issue: unknown test"
570
+ " convertion mode %s.", mode.name());
571
throw new Error(msg);
572
}
573
if (!failureExpected
574
&& (expectedResult != null && !expectedResult.equals(result)
575
|| expectedResult == null && result != null)) {
576
String msg = String.format("Conversion result %s is not equal"
577
+ " to the expected result %10s",
578
result, expectedResult);
579
throw new AssertionError(msg);
580
}
581
if (VERBOSE) {
582
String resultStr;
583
if (result != null) {
584
resultStr = String.format("Converted value and type are"
585
+ " %10s (%10s)", "'" + result + "'",
586
result.getClass().getSimpleName());
587
} else {
588
resultStr = String.format("Converted value is %10s", result);
589
}
590
System.out.println(resultStr);
591
}
592
if (failureExpected) {
593
String msg = String.format("No exception thrown while testing"
594
+ " return value conversion: %10s => %10s;"
595
+ " parameter: %10s",
596
from, to, param);
597
throw new AssertionError(msg);
598
}
599
} catch (AssertionError e) {
600
throw e; // report test failure
601
} catch (Throwable e) {
602
if (VERBOSE) {
603
System.out.printf("%s: %s\n", e.getClass(), e.getMessage());
604
}
605
if (!failureExpected || !e.getClass().equals(expectedException)) {
606
String msg = String.format("Unexpected exception was thrown"
607
+ " while testing return value conversion:"
608
+ " %s => %s; parameter: %s", from, to, param);
609
throw new AssertionError(msg, e);
610
}
611
}
612
}
613
}
614
615