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