1 /*
2  * Copyright (C) 2018 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 
17 import java.lang.invoke.MethodHandles;
18 import java.lang.invoke.VarHandle;
19 import java.lang.invoke.WrongMethodTypeException;
20 import java.nio.ByteBuffer;
21 import java.nio.ByteOrder;
22 
23 public class VarHandleTypeConversionTests {
24     public static class VoidReturnTypeTest extends VarHandleUnitTest {
25         private int i;
26         private static final VarHandle vh;
27 
28         static {
29             try {
30                 Class<?> cls = VoidReturnTypeTest.class;
31                 vh = MethodHandles.lookup().findVarHandle(cls, "i", int.class);
32             } catch (Exception e) {
33                 throw new RuntimeException(e);
34             }
35         }
36 
37         @Override
doTest()38         protected void doTest() {
39             // Void is always okay for a return type.
40             vh.setVolatile(this, 33);
41             vh.get(this);
42             vh.compareAndSet(this, 33, 44);
43             vh.compareAndSet(this, 27, 16);
44             vh.weakCompareAndSet(this, 17, 19);
45             vh.getAndSet(this, 200000);
46             vh.getAndBitwiseXor(this, 0x5a5a5a5a);
47             vh.getAndAdd(this, 99);
48         }
49 
main(String[] args)50         public static void main(String[] args) {
51             new VoidReturnTypeTest().run();
52         }
53     }
54 
55     //
56     // Tests that a null reference as a boxed primitive type argument
57     // throws a NullPointerException. These vary the VarHandle type
58     // with each primitive for coverage.
59     //
60 
61     public static class BoxedNullBooleanThrowsNPETest extends VarHandleUnitTest {
62         private static boolean z;
63         private static final VarHandle vh;
64 
65         static {
66             try {
67                 Class<?> cls = BoxedNullBooleanThrowsNPETest.class;
68                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "z", boolean.class);
69             } catch (Exception e) {
70                 throw new RuntimeException(e);
71             }
72         }
73 
74         @Override
doTest()75         protected void doTest() {
76             Boolean newValue = null;
77             try {
78                 vh.getAndSet(newValue);
79                 failUnreachable();
80             } catch (NullPointerException ex) {
81             }
82         }
83 
main(String[] args)84         public static void main(String[] args) {
85             new BoxedNullBooleanThrowsNPETest().run();
86         }
87     }
88 
89     public static class BoxedNullByteThrowsNPETest extends VarHandleUnitTest {
90         private byte b;
91         private static final VarHandle vh;
92 
93         static {
94             try {
95                 Class<?> cls = BoxedNullByteThrowsNPETest.class;
96                 vh = MethodHandles.lookup().findVarHandle(cls, "b", byte.class);
97             } catch (Exception e) {
98                 throw new RuntimeException(e);
99             }
100         }
101 
102         @Override
doTest()103         protected void doTest() {
104             Byte newValue = null;
105             try {
106                 vh.getAndSet(this, newValue);
107                 failUnreachable();
108             } catch (NullPointerException ex) {
109             }
110         }
111 
main(String[] args)112         public static void main(String[] args) {
113             new BoxedNullByteThrowsNPETest().run();
114         }
115     }
116 
117     public static class BoxedNullCharacterThrowsNPETest extends VarHandleUnitTest {
118         private static final VarHandle vh;
119 
120         static {
121             try {
122                 vh = MethodHandles.arrayElementVarHandle(char[].class);
123             } catch (Exception e) {
124                 throw new RuntimeException(e);
125             }
126         }
127 
128         @Override
doTest()129         protected void doTest() {
130             char[] values = new char[3];
131             Character newValue = null;
132             try {
133                 vh.getAndSet(values, 0, newValue);
134                 failUnreachable();
135             } catch (NullPointerException ex) {
136             }
137         }
138 
main(String[] args)139         public static void main(String[] args) {
140             new BoxedNullCharacterThrowsNPETest().run();
141         }
142     }
143 
144     public static class BoxedNullShortThrowsNPETest extends VarHandleUnitTest {
145         private static final VarHandle vh;
146 
147         static {
148             try {
149                 Class<?> cls = BoxedNullShortThrowsNPETest.class;
150                 vh = MethodHandles.byteArrayViewVarHandle(short[].class, ByteOrder.LITTLE_ENDIAN);
151             } catch (Exception e) {
152                 throw new RuntimeException(e);
153             }
154         }
155 
156         @Override
doTest()157         protected void doTest() {
158             byte[] bytes = new byte[2 * Short.SIZE];
159             int index = VarHandleUnitTestHelpers.alignedOffset_short(bytes, 0);
160             Short newValue = null;
161             try {
162                 vh.set(bytes, index, newValue);
163                 failUnreachable();
164             } catch (NullPointerException ex) {
165             }
166         }
167 
main(String[] args)168         public static void main(String[] args) {
169             new BoxedNullShortThrowsNPETest().run();
170         }
171     }
172 
173     public static class BoxedNullIntegerThrowsNPETest extends VarHandleUnitTest {
174         private static final VarHandle vh;
175 
176         static {
177             try {
178                 vh = MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.BIG_ENDIAN);
179             } catch (Exception e) {
180                 throw new RuntimeException(e);
181             }
182         }
183 
184         @Override
doTest()185         protected void doTest() {
186             byte[] bytes = new byte[2 * Integer.SIZE];
187             int index = VarHandleUnitTestHelpers.alignedOffset_int(bytes, 0);
188             Integer newValue = null;
189             try {
190                 vh.setVolatile(bytes, index, newValue);
191                 failUnreachable();
192             } catch (NullPointerException ex) {
193             }
194         }
195 
main(String[] args)196         public static void main(String[] args) {
197             new BoxedNullIntegerThrowsNPETest().run();
198         }
199     }
200 
201     public static class BoxedNullLongThrowsNPETest extends VarHandleUnitTest {
202         private static final VarHandle vh;
203 
204         static {
205             try {
206                 Class<?> cls = BoxedNullLongThrowsNPETest.class;
207                 vh = MethodHandles.byteBufferViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN);
208             } catch (Exception e) {
209                 throw new RuntimeException(e);
210             }
211         }
212 
213         @Override
doTest()214         protected void doTest() {
215             ByteBuffer bb = ByteBuffer.allocateDirect(2 * Long.SIZE);
216             int index = VarHandleUnitTestHelpers.alignedOffset_long(bb, 0);
217             Long newValue = null;
218             try {
219                 vh.getAndAdd(bb, index, newValue);
220                 failUnreachable();
221             } catch (NullPointerException ex) {
222             }
223         }
224 
main(String[] args)225         public static void main(String[] args) {
226             new BoxedNullLongThrowsNPETest().run();
227         }
228     }
229 
230     public static class BoxedNullFloatThrowsNPETest extends VarHandleUnitTest {
231         private static final VarHandle vh;
232 
233         static {
234             try {
235                 Class<?> cls = BoxedNullFloatThrowsNPETest.class;
236                 vh = MethodHandles.byteBufferViewVarHandle(float[].class, ByteOrder.BIG_ENDIAN);
237             } catch (Exception e) {
238                 throw new RuntimeException(e);
239             }
240         }
241 
242         @Override
doTest()243         protected void doTest() {
244             ByteBuffer bb = ByteBuffer.allocate(2 * Float.SIZE);
245             int index = VarHandleUnitTestHelpers.alignedOffset_float(bb, 0);
246             Float newValue = null;
247             try {
248                 vh.set(bb, index, newValue);
249                 failUnreachable();
250             } catch (NullPointerException ex) {
251             }
252         }
253 
main(String[] args)254         public static void main(String[] args) {
255             new BoxedNullFloatThrowsNPETest().run();
256         }
257     }
258 
259     public static class BoxedNullDoubleThrowsNPETest extends VarHandleUnitTest {
260         private double d;
261         private static final VarHandle vh;
262 
263         static {
264             try {
265                 vh = MethodHandles.byteBufferViewVarHandle(double[].class, ByteOrder.LITTLE_ENDIAN);
266             } catch (Exception e) {
267                 throw new RuntimeException(e);
268             }
269         }
270 
271         @Override
doTest()272         protected void doTest() {
273             byte[] bytes = new byte[3 * Double.SIZE];
274             int offset = 1;
275             ByteBuffer bb = ByteBuffer.wrap(bytes, offset, bytes.length - offset);
276             int index = VarHandleUnitTestHelpers.alignedOffset_double(bb, 0);
277             Double newValue = null;
278             try {
279                 vh.set(bb, index, newValue);
280                 failUnreachable();
281             } catch (NullPointerException ex) {
282             }
283         }
284 
main(String[] args)285         public static void main(String[] args) {
286             new BoxedNullDoubleThrowsNPETest().run();
287         }
288     }
289 
290     public static class WideningBooleanArgumentTest extends VarHandleUnitTest {
291         private static boolean v;
292         private static final VarHandle vh;
293 
294         static {
295             try {
296                 Class<?> cls = WideningBooleanArgumentTest.class;
297                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", boolean.class);
298             } catch (Exception e) {
299                 throw new RuntimeException(e);
300             }
301         }
302 
303         @Override
doTest()304         protected void doTest() {
305             vh.set(true);
306             try {
307                 vh.set((byte) 3);
308                 failUnreachable();
309             } catch (WrongMethodTypeException ex) {
310             }
311             try {
312                 vh.set('c');
313                 failUnreachable();
314             } catch (WrongMethodTypeException ex) {
315             }
316             try {
317                 vh.set((short) 1);
318                 failUnreachable();
319             } catch (WrongMethodTypeException ex) {
320             }
321             try {
322                 vh.set((int) 1);
323                 failUnreachable();
324             } catch (WrongMethodTypeException ex) {
325             }
326             try {
327                 vh.set((long) 1);
328                 failUnreachable();
329             } catch (WrongMethodTypeException ex) {
330             }
331             try {
332                 vh.set((float) 1.0f);
333                 failUnreachable();
334             } catch (WrongMethodTypeException ex) {
335             }
336             try {
337                 vh.set((double) 1.0);
338                 failUnreachable();
339             } catch (WrongMethodTypeException ex) {
340             }
341         }
342 
main(String[] args)343         public static void main(String[] args) {
344             new WideningBooleanArgumentTest().run();
345         }
346     }
347 
348     public static class WideningByteArgumentTest extends VarHandleUnitTest {
349         private static byte v;
350         private static final VarHandle vh;
351 
352         static {
353             try {
354                 Class<?> cls = WideningByteArgumentTest.class;
355                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", byte.class);
356             } catch (Exception e) {
357                 throw new RuntimeException(e);
358             }
359         }
360 
361         @Override
doTest()362         protected void doTest() {
363             try {
364                 vh.set(true);
365                 failUnreachable();
366             } catch (WrongMethodTypeException ex) {
367             }
368             vh.set((byte) 3);
369             try {
370                 vh.set('c');
371                 failUnreachable();
372             } catch (WrongMethodTypeException ex) {
373             }
374             try {
375                 vh.set((short) 1);
376                 failUnreachable();
377             } catch (WrongMethodTypeException ex) {
378             }
379             try {
380                 vh.set((int) 1);
381                 failUnreachable();
382             } catch (WrongMethodTypeException ex) {
383             }
384             try {
385                 vh.set((long) 1);
386                 failUnreachable();
387             } catch (WrongMethodTypeException ex) {
388             }
389             try {
390                 vh.set((float) 1.0f);
391                 failUnreachable();
392             } catch (WrongMethodTypeException ex) {
393             }
394             try {
395                 vh.set((double) 1.0);
396                 failUnreachable();
397             } catch (WrongMethodTypeException ex) {
398             }
399         }
400 
main(String[] args)401         public static void main(String[] args) {
402             new WideningByteArgumentTest().run();
403         }
404     }
405 
406     public static class WideningCharacterArgumentTest extends VarHandleUnitTest {
407         private static char v;
408         private static final VarHandle vh;
409 
410         static {
411             try {
412                 Class<?> cls = WideningCharacterArgumentTest.class;
413                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", char.class);
414             } catch (Exception e) {
415                 throw new RuntimeException(e);
416             }
417         }
418 
419         @Override
doTest()420         protected void doTest() {
421             try {
422                 vh.set(true);
423                 failUnreachable();
424             } catch (WrongMethodTypeException ex) {
425             }
426             try {
427                 vh.set((byte) 3);
428                 failUnreachable();
429             } catch (WrongMethodTypeException ex) {
430             }
431             vh.set('c');
432             try {
433                 vh.set((short) 1);
434                 failUnreachable();
435             } catch (WrongMethodTypeException ex) {
436             }
437             try {
438                 vh.set((int) 1);
439                 failUnreachable();
440             } catch (WrongMethodTypeException ex) {
441             }
442             try {
443                 vh.set((long) 1);
444                 failUnreachable();
445             } catch (WrongMethodTypeException ex) {
446             }
447             try {
448                 vh.set((float) 1.0f);
449                 failUnreachable();
450             } catch (WrongMethodTypeException ex) {
451             }
452             try {
453                 vh.set((double) 1.0);
454                 failUnreachable();
455             } catch (WrongMethodTypeException ex) {
456             }
457         }
458 
main(String[] args)459         public static void main(String[] args) {
460             new WideningCharacterArgumentTest().run();
461         }
462     }
463 
464     public static class WideningShortArgumentTest extends VarHandleUnitTest {
465         private static short v;
466         private static final VarHandle vh;
467 
468         static {
469             try {
470                 Class<?> cls = WideningShortArgumentTest.class;
471                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", short.class);
472             } catch (Exception e) {
473                 throw new RuntimeException(e);
474             }
475         }
476 
477         @Override
doTest()478         protected void doTest() {
479             try {
480                 vh.set(true);
481                 failUnreachable();
482             } catch (WrongMethodTypeException ex) {
483             }
484             vh.set((byte) 3);
485             try {
486                 vh.set('c');
487                 failUnreachable();
488             } catch (WrongMethodTypeException ex) {
489             }
490             vh.set((short) 1);
491             try {
492                 vh.set((int) 1);
493                 failUnreachable();
494             } catch (WrongMethodTypeException ex) {
495             }
496             try {
497                 vh.set((long) 1);
498                 failUnreachable();
499             } catch (WrongMethodTypeException ex) {
500             }
501             try {
502                 vh.set((float) 1.0f);
503                 failUnreachable();
504             } catch (WrongMethodTypeException ex) {
505             }
506             try {
507                 vh.set((double) 1.0);
508                 failUnreachable();
509             } catch (WrongMethodTypeException ex) {
510             }
511         }
512 
main(String[] args)513         public static void main(String[] args) {
514             new WideningShortArgumentTest().run();
515         }
516     }
517 
518     public static class WideningIntegerArgumentTest extends VarHandleUnitTest {
519         private static int v;
520         private static final VarHandle vh;
521 
522         static {
523             try {
524                 Class<?> cls = WideningIntegerArgumentTest.class;
525                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", int.class);
526             } catch (Exception e) {
527                 throw new RuntimeException(e);
528             }
529         }
530 
531         @Override
doTest()532         protected void doTest() {
533             try {
534                 vh.set(true);
535                 failUnreachable();
536             } catch (WrongMethodTypeException ex) {
537             }
538             vh.set((byte) 3);
539             vh.set('c');
540             vh.set((char) 0x8fff);
541             assertEquals(0x8fff, v);
542             vh.set((short) 1);
543             vh.set((int) 1);
544             try {
545                 vh.set((long) 1);
546                 failUnreachable();
547             } catch (WrongMethodTypeException ex) {
548             }
549             try {
550                 vh.set((float) 1.0f);
551                 failUnreachable();
552             } catch (WrongMethodTypeException ex) {
553             }
554             try {
555                 vh.set((double) 1.0);
556                 failUnreachable();
557             } catch (WrongMethodTypeException ex) {
558             }
559         }
560 
main(String[] args)561         public static void main(String[] args) {
562             new WideningIntegerArgumentTest().run();
563         }
564     }
565 
566     public static class WideningLongArgumentTest extends VarHandleUnitTest {
567         private static long v;
568         private static final VarHandle vh;
569 
570         static {
571             try {
572                 Class<?> cls = WideningLongArgumentTest.class;
573                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", long.class);
574             } catch (Exception e) {
575                 throw new RuntimeException(e);
576             }
577         }
578 
579         @Override
doTest()580         protected void doTest() {
581             try {
582                 vh.set(true);
583                 failUnreachable();
584             } catch (WrongMethodTypeException ex) {
585             }
586             vh.set((byte) 3);
587             vh.set('c');
588             vh.set((short) 1);
589             vh.set((int) 1);
590             vh.set((long) 1);
591             try {
592                 vh.set((float) 1.0f);
593                 failUnreachable();
594             } catch (WrongMethodTypeException ex) {
595             }
596             try {
597                 vh.set((double) 1.0);
598                 failUnreachable();
599             } catch (WrongMethodTypeException ex) {
600             }
601         }
602 
main(String[] args)603         public static void main(String[] args) {
604             new WideningLongArgumentTest().run();
605         }
606     }
607 
608     public static class WideningFloatArgumentTest extends VarHandleUnitTest {
609         private static float v;
610         private static final VarHandle vh;
611 
612         static {
613             try {
614                 Class<?> cls = WideningFloatArgumentTest.class;
615                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", float.class);
616             } catch (Exception e) {
617                 throw new RuntimeException(e);
618             }
619         }
620 
621         @Override
doTest()622         protected void doTest() {
623             try {
624                 vh.set(true);
625                 failUnreachable();
626             } catch (WrongMethodTypeException ex) {
627             }
628             vh.set((byte) 3);
629             vh.set('c');
630             vh.set((short) 1);
631             vh.set((int) 1);
632             vh.set((long) 1);
633             vh.set((float) 1.0f);
634             try {
635                 vh.set((double) 1.0);
636                 failUnreachable();
637             } catch (WrongMethodTypeException ex) {
638             }
639         }
640 
main(String[] args)641         public static void main(String[] args) {
642             new WideningFloatArgumentTest().run();
643         }
644     }
645 
646     public static class WideningDoubleArgumentTest extends VarHandleUnitTest {
647         private static double v;
648         private static final VarHandle vh;
649 
650         static {
651             try {
652                 Class<?> cls = WideningDoubleArgumentTest.class;
653                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", double.class);
654             } catch (Exception e) {
655                 throw new RuntimeException(e);
656             }
657         }
658 
659         @Override
doTest()660         protected void doTest() {
661             try {
662                 vh.set(true);
663                 failUnreachable();
664             } catch (WrongMethodTypeException ex) {
665             }
666             vh.set((byte) 3);
667             vh.set('c');
668             vh.set((short) 1);
669             vh.set((int) 1);
670             vh.set((long) 1);
671             vh.set((double) 1.0f);
672             vh.set((double) 1.0);
673         }
674 
main(String[] args)675         public static void main(String[] args) {
676             new WideningDoubleArgumentTest().run();
677         }
678     }
679 
680     public static class WideningBooleanReturnValueTest extends VarHandleUnitTest {
681         private static boolean v;
682         private static final VarHandle vh;
683 
684         static {
685             try {
686                 Class<?> cls = WideningBooleanReturnValueTest.class;
687                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", boolean.class);
688             } catch (Exception e) {
689                 throw new RuntimeException(e);
690             }
691         }
692 
693         @Override
doTest()694         protected void doTest() {
695             vh.set(true);
696             vh.get();
697             boolean z = (boolean) vh.get();
698             try {
699                 byte b = (byte) vh.get();
700                 failUnreachable();
701             } catch (WrongMethodTypeException ex) {
702             }
703             try {
704                 char c = (char) vh.get();
705                 failUnreachable();
706             } catch (WrongMethodTypeException ex) {
707             }
708             try {
709                 short s = (short) vh.get();
710                 failUnreachable();
711             } catch (WrongMethodTypeException ex) {
712             }
713             try {
714                 int i = (int) vh.get();
715                 failUnreachable();
716             } catch (WrongMethodTypeException ex) {
717             }
718             try {
719                 long j = (long) vh.get();
720                 failUnreachable();
721             } catch (WrongMethodTypeException ex) {
722             }
723             try {
724                 float f = (float) vh.get();
725                 failUnreachable();
726             } catch (WrongMethodTypeException ex) {
727             }
728             try {
729                 double d = (double) vh.get();
730                 failUnreachable();
731             } catch (WrongMethodTypeException ex) {
732             }
733         }
734 
main(String[] args)735         public static void main(String[] args) {
736             new WideningBooleanReturnValueTest().run();
737         }
738     }
739 
740     public static class WideningByteReturnValueTest extends VarHandleUnitTest {
741         private static byte v;
742         private static final VarHandle vh;
743 
744         static {
745             try {
746                 Class<?> cls = WideningByteReturnValueTest.class;
747                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", byte.class);
748             } catch (Exception e) {
749                 throw new RuntimeException(e);
750             }
751         }
752 
753         @Override
doTest()754         protected void doTest() {
755             vh.set((byte) 3);
756             vh.get();
757             try {
758                 boolean z = (boolean) vh.get();
759                 failUnreachable();
760             } catch (WrongMethodTypeException ex) {
761             }
762 
763             byte b = (byte) vh.get();
764             try {
765                 char c = (char) vh.get();
766                 failUnreachable();
767             } catch (WrongMethodTypeException ex) {
768             }
769             short s = (short) vh.get();
770             int i = (int) vh.get();
771             long j = (long) vh.get();
772             float f = (float) vh.get();
773             double d = (double) vh.get();
774         }
775 
main(String[] args)776         public static void main(String[] args) {
777             new WideningByteReturnValueTest().run();
778         }
779     }
780 
781     public static class WideningCharacterReturnValueTest extends VarHandleUnitTest {
782         private static char v;
783         private static final VarHandle vh;
784 
785         static {
786             try {
787                 Class<?> cls = WideningCharacterReturnValueTest.class;
788                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", char.class);
789             } catch (Exception e) {
790                 throw new RuntimeException(e);
791             }
792         }
793 
main(String[] args)794         public static void main(String[] args) {
795             new WideningCharacterReturnValueTest().run();
796         }
797 
798         @Override
doTest()799         protected void doTest() {
800             vh.set('c');
801             vh.get();
802             try {
803                 boolean z = (boolean) vh.get();
804                 failUnreachable();
805             } catch (WrongMethodTypeException ex) {
806             }
807             try {
808                 byte b = (byte) vh.get();
809                 failUnreachable();
810             } catch (WrongMethodTypeException ex) {
811             }
812             char c = (char) vh.get();
813             try {
814                 short s = (short) vh.get();
815                 failUnreachable();
816             } catch (WrongMethodTypeException ex) {
817             }
818             int i = (int) vh.get();
819             long j = (long) vh.get();
820             float f = (float) vh.get();
821             double d = (double) vh.get();
822         }
823     }
824 
825     public static class WideningShortReturnValueTest extends VarHandleUnitTest {
826         private static short v;
827         private static final VarHandle vh;
828 
829         static {
830             try {
831                 Class<?> cls = WideningShortReturnValueTest.class;
832                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", short.class);
833             } catch (Exception e) {
834                 throw new RuntimeException(e);
835             }
836         }
837 
main(String[] args)838         public static void main(String[] args) {
839             new WideningShortReturnValueTest().run();
840         }
841 
842         @Override
doTest()843         protected void doTest() {
844             vh.set((short) 8888);
845             vh.get();
846             try {
847                 boolean z = (boolean) vh.get();
848                 failUnreachable();
849             } catch (WrongMethodTypeException ex) {
850             }
851             try {
852                 byte b = (byte) vh.get();
853                 failUnreachable();
854             } catch (WrongMethodTypeException ex) {
855             }
856             try {
857                 char c = (char) vh.get();
858                 failUnreachable();
859             } catch (WrongMethodTypeException ex) {
860             }
861             short s = (short) vh.get();
862             int i = (int) vh.get();
863             long j = (long) vh.get();
864             float f = (float) vh.get();
865             double d = (double) vh.get();
866         }
867     }
868 
869     public static class WideningIntegerReturnValueTest extends VarHandleUnitTest {
870         private static int v;
871         private static final VarHandle vh;
872 
873         static {
874             try {
875                 Class<?> cls = WideningIntegerReturnValueTest.class;
876                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", int.class);
877             } catch (Exception e) {
878                 throw new RuntimeException(e);
879             }
880         }
881 
main(String[] args)882         public static void main(String[] args) {
883             new WideningIntegerReturnValueTest().run();
884         }
885 
886         @Override
doTest()887         protected void doTest() {
888             vh.set(0x1234fedc);
889             vh.get();
890             try {
891                 boolean z = (boolean) vh.get();
892                 failUnreachable();
893             } catch (WrongMethodTypeException ex) {
894             }
895             try {
896                 byte b = (byte) vh.get();
897                 failUnreachable();
898             } catch (WrongMethodTypeException ex) {
899             }
900             try {
901                 char c = (char) vh.get();
902                 failUnreachable();
903             } catch (WrongMethodTypeException ex) {
904             }
905             try {
906                 short s = (short) vh.get();
907                 failUnreachable();
908             } catch (WrongMethodTypeException ex) {
909             }
910             int i = (int) vh.get();
911             long j = (long) vh.get();
912             float f = (float) vh.get();
913             double d = (double) vh.get();
914         }
915     }
916 
917     public static class WideningLongReturnValueTest extends VarHandleUnitTest {
918         private static long v;
919         private static final VarHandle vh;
920 
921         static {
922             try {
923                 Class<?> cls = WideningLongReturnValueTest.class;
924                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", long.class);
925             } catch (Exception e) {
926                 throw new RuntimeException(e);
927             }
928         }
929 
main(String[] args)930         public static void main(String[] args) {
931             new WideningLongReturnValueTest().run();
932         }
933 
934         @Override
doTest()935         protected void doTest() {
936             vh.set(0xfedcba987654321l);
937             vh.get();
938             try {
939                 boolean z = (boolean) vh.get();
940                 failUnreachable();
941             } catch (WrongMethodTypeException ex) {
942             }
943             try {
944                 byte b = (byte) vh.get();
945                 failUnreachable();
946             } catch (WrongMethodTypeException ex) {
947             }
948             try {
949                 char c = (char) vh.get();
950                 failUnreachable();
951             } catch (WrongMethodTypeException ex) {
952             }
953             try {
954                 short s = (short) vh.get();
955                 failUnreachable();
956             } catch (WrongMethodTypeException ex) {
957             }
958             try {
959                 int i = (int) vh.get();
960                 failUnreachable();
961             } catch (WrongMethodTypeException ex) {
962             }
963             long j = (long) vh.get();
964             float f = (float) vh.get();
965             double d = (double) vh.get();
966         }
967     }
968 
969     public static class WideningFloatReturnValueTest extends VarHandleUnitTest {
970         private static float v;
971         private static final VarHandle vh;
972 
973         static {
974             try {
975                 Class<?> cls = WideningFloatReturnValueTest.class;
976                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", float.class);
977             } catch (Exception e) {
978                 throw new RuntimeException(e);
979             }
980         }
981 
main(String[] args)982         public static void main(String[] args) {
983             new WideningFloatReturnValueTest().run();
984         }
985 
986         @Override
doTest()987         protected void doTest() {
988             vh.set(7.77e20f);
989             vh.get();
990             try {
991                 boolean z = (boolean) vh.get();
992                 failUnreachable();
993             } catch (WrongMethodTypeException ex) {
994             }
995             try {
996                 byte b = (byte) vh.get();
997                 failUnreachable();
998             } catch (WrongMethodTypeException ex) {
999             }
1000             try {
1001                 char c = (char) vh.get();
1002                 failUnreachable();
1003             } catch (WrongMethodTypeException ex) {
1004             }
1005             try {
1006                 short s = (short) vh.get();
1007                 failUnreachable();
1008             } catch (WrongMethodTypeException ex) {
1009             }
1010             try {
1011                 int i = (int) vh.get();
1012                 failUnreachable();
1013             } catch (WrongMethodTypeException ex) {
1014             }
1015             try {
1016                 long j = (long) vh.get();
1017                 failUnreachable();
1018             } catch (WrongMethodTypeException ex) {
1019             }
1020             float f = (float) vh.get();
1021             double d = (double) vh.get();
1022         }
1023     }
1024 
1025     public static class WideningDoubleReturnValueTest extends VarHandleUnitTest {
1026         private static double v;
1027         private static final VarHandle vh;
1028 
1029         static {
1030             try {
1031                 Class<?> cls = WideningDoubleReturnValueTest.class;
1032                 vh = MethodHandles.lookup().findStaticVarHandle(cls, "v", double.class);
1033             } catch (Exception e) {
1034                 throw new RuntimeException(e);
1035             }
1036         }
1037 
main(String[] args)1038         public static void main(String[] args) {
1039             new WideningDoubleReturnValueTest().run();
1040         }
1041 
1042         @Override
doTest()1043         protected void doTest() {
1044             vh.set(Math.E);
1045             vh.get();
1046             try {
1047                 boolean z = (boolean) vh.get();
1048                 failUnreachable();
1049             } catch (WrongMethodTypeException ex) {
1050             }
1051             try {
1052                 byte b = (byte) vh.get();
1053                 failUnreachable();
1054             } catch (WrongMethodTypeException ex) {
1055             }
1056             try {
1057                 char c = (char) vh.get();
1058                 failUnreachable();
1059             } catch (WrongMethodTypeException ex) {
1060             }
1061             try {
1062                 short s = (short) vh.get();
1063                 failUnreachable();
1064             } catch (WrongMethodTypeException ex) {
1065             }
1066             try {
1067                 int i = (int) vh.get();
1068                 failUnreachable();
1069             } catch (WrongMethodTypeException ex) {
1070             }
1071             try {
1072                 long j = (long) vh.get();
1073                 failUnreachable();
1074             } catch (WrongMethodTypeException ex) {
1075             }
1076             try {
1077                 float f = (float) vh.get();
1078                 failUnreachable();
1079             } catch (WrongMethodTypeException ex) {
1080             }
1081             double d = (double) vh.get();
1082         }
1083     }
1084 
1085     public static class SubtypeTest extends VarHandleUnitTest {
1086         private static final Widget INITIAL_VALUE = Widget.ONE;
1087         private static final VarHandle vh;
1088         private Widget w = INITIAL_VALUE;
1089 
1090         static {
1091             try {
1092                 vh = MethodHandles.lookup().findVarHandle(SubtypeTest.class, "w", Widget.class);
1093             } catch (Exception e) {
1094                 throw new RuntimeException(e);
1095             }
1096         }
1097 
main(String[] args)1098         public static void main(String[] args) {
1099             new SubtypeTest().run();
1100         }
1101 
1102         // A sub-type of the Widget class
1103         public static class WidgetChild extends Widget {
1104             private int weight;
1105 
WidgetChild(int requistionNumber, int weight)1106             public WidgetChild(int requistionNumber, int weight) {
1107                 super(requistionNumber);
1108                 this.weight = weight;
1109             }
1110 
1111             @Override
equals(Object o)1112             public boolean equals(Object o) {
1113                 if (this == o) {
1114                     return true;
1115                 }
1116                 if (o instanceof WidgetChild == false) {
1117                     return false;
1118                 }
1119                 WidgetChild wc = (WidgetChild) o;
1120                 return (requisitionNumber == wc.requisitionNumber && weight == wc.weight);
1121             }
1122 
1123             public static final WidgetChild ONE = new WidgetChild(1, 100);
1124             public static final WidgetChild TWO = new WidgetChild(2, 2000);
1125         }
1126 
1127         @Override
doTest()1128         public void doTest() {
1129             assertEquals(INITIAL_VALUE, vh.getVolatile(this));
1130             vh.setVolatile(this, null);
1131             Widget rw = (Widget) vh.compareAndExchange(this, null, WidgetChild.ONE);
1132             assertEquals(null, rw);
1133             assertEquals(WidgetChild.ONE, this.w);
1134             WidgetChild rwc =
1135                     (WidgetChild)
1136                             vh.compareAndExchangeRelease(this, WidgetChild.ONE, WidgetChild.TWO);
1137             assertEquals(WidgetChild.TWO, w);
1138             rwc = (WidgetChild) vh.compareAndExchangeAcquire(this, WidgetChild.TWO, Widget.ONE);
1139             assertEquals(Widget.ONE, w);
1140             assertEquals(false, (boolean) vh.compareAndSet(this, null, null));
1141             assertEquals(true, vh.compareAndSet(this, Widget.ONE, Widget.TWO));
1142             assertEquals(Widget.TWO, w);
1143             vh.set(this, null);
1144             assertEquals(null, (Widget) vh.get(this));
1145             vh.setRelease(this, WidgetChild.ONE);
1146             assertEquals(WidgetChild.ONE, (WidgetChild) vh.getAcquire(this));
1147             assertEquals(WidgetChild.ONE, w);
1148             vh.setOpaque(this, WidgetChild.TWO);
1149             assertEquals(WidgetChild.TWO, vh.getOpaque(this));
1150             assertEquals(WidgetChild.TWO, w);
1151             vh.setVolatile(this, null);
1152             assertEquals(null, (Widget) vh.getVolatile(this));
1153             assertEquals(null, w);
1154             assertEquals(null, (WidgetChild) vh.getAndSet(this, WidgetChild.ONE));
1155             assertEquals(WidgetChild.ONE, w);
1156             assertEquals(WidgetChild.ONE, (WidgetChild) vh.getAndSetRelease(this, WidgetChild.TWO));
1157             assertEquals(WidgetChild.TWO, (WidgetChild) vh.getAndSetAcquire(this, WidgetChild.ONE));
1158             try {
1159                 WidgetChild result = (WidgetChild) vh.getAndAdd(this, WidgetChild.ONE);
1160                 failUnreachable();
1161             } catch (UnsupportedOperationException e) {
1162             }
1163             try {
1164                 WidgetChild result = (WidgetChild) vh.getAndAddAcquire(this, 1);
1165                 failUnreachable();
1166             } catch (UnsupportedOperationException e) {
1167             }
1168             try {
1169                 WidgetChild result = (WidgetChild) vh.getAndAddRelease(this, 1);
1170                 failUnreachable();
1171             } catch (UnsupportedOperationException e) {
1172             }
1173             try {
1174                 WidgetChild result = (WidgetChild) vh.getAndBitwiseAnd(this, 1);
1175                 failUnreachable();
1176             } catch (UnsupportedOperationException e) {
1177             }
1178             try {
1179                 WidgetChild result = (WidgetChild) vh.getAndBitwiseAndAcquire(this, 1);
1180                 failUnreachable();
1181             } catch (UnsupportedOperationException e) {
1182             }
1183             try {
1184                 WidgetChild result = (WidgetChild) vh.getAndBitwiseAndRelease(this, 1);
1185                 failUnreachable();
1186             } catch (UnsupportedOperationException e) {
1187             }
1188             try {
1189                 WidgetChild result = (WidgetChild) vh.getAndBitwiseOr(this, 1);
1190                 failUnreachable();
1191             } catch (UnsupportedOperationException e) {
1192             }
1193             try {
1194                 WidgetChild result = (WidgetChild) vh.getAndBitwiseOrAcquire(this, 1);
1195                 failUnreachable();
1196             } catch (UnsupportedOperationException e) {
1197             }
1198             try {
1199                 WidgetChild result = (WidgetChild) vh.getAndBitwiseOrRelease(this, 1);
1200                 failUnreachable();
1201             } catch (UnsupportedOperationException e) {
1202             }
1203             try {
1204                 WidgetChild result = (WidgetChild) vh.getAndBitwiseXor(this, 1);
1205                 failUnreachable();
1206             } catch (UnsupportedOperationException e) {
1207             }
1208             try {
1209                 WidgetChild result = (WidgetChild) vh.getAndBitwiseXorAcquire(this, 1);
1210                 failUnreachable();
1211             } catch (UnsupportedOperationException e) {
1212             }
1213             try {
1214                 WidgetChild result = (WidgetChild) vh.getAndBitwiseXorRelease(this, 1);
1215                 failUnreachable();
1216             } catch (UnsupportedOperationException e) {
1217             }
1218         }
1219     }
1220 
1221     public static class SupertypeTest extends VarHandleUnitTest {
1222         private Widget w = null;
1223         private static final VarHandle vh;
1224 
1225         static {
1226             try {
1227                 vh = MethodHandles.lookup().findVarHandle(SupertypeTest.class, "w", Widget.class);
1228             } catch (Exception e) {
1229                 throw new RuntimeException(e);
1230             }
1231         }
1232 
main(String[] args)1233         public static void main(String[] args) {
1234             new SupertypeTest().run();
1235         }
1236 
1237         @Override
doTest()1238         public void doTest() {
1239             assertEquals(null, (Object) vh.get(this));
1240             vh.set(this, Widget.ONE);
1241             assertEquals(Widget.ONE, vh.getVolatile(this));
1242             try {
1243                 vh.setVolatile(this, new Object());
1244             } catch (ClassCastException e) {
1245             }
1246         }
1247     }
1248 
1249     public static class ImplicitBoxingIntegerTest extends VarHandleUnitTest {
1250         private static Integer field;
1251         private static final VarHandle vh;
1252 
1253         static {
1254             try {
1255                 vh =
1256                         MethodHandles.lookup()
1257                                 .findStaticVarHandle(
1258                                         ImplicitBoxingIntegerTest.class, "field", Integer.class);
1259             } catch (Exception e) {
1260                 throw new RuntimeException(e);
1261             }
1262         }
1263 
main(String[] args)1264         public static void main(String[] args) {
1265             new ImplicitBoxingIntegerTest().run();
1266         }
1267 
1268         @Override
doTest()1269         public void doTest() {
1270             try {
1271                 vh.set(true);
1272                 failUnreachable();
1273             } catch (WrongMethodTypeException e) {
1274             }
1275             try {
1276                 vh.set((byte) 0);
1277                 failUnreachable();
1278             } catch (WrongMethodTypeException e) {
1279             }
1280             try {
1281                 vh.set((short) 1);
1282                 failUnreachable();
1283             } catch (WrongMethodTypeException e) {
1284             }
1285             try {
1286                 vh.set('A');
1287                 failUnreachable();
1288             } catch (WrongMethodTypeException e) {
1289             }
1290             vh.set(2);
1291             try {
1292                 vh.setRelease(Long.MAX_VALUE);
1293             } catch (WrongMethodTypeException e) {
1294             }
1295             try {
1296                 vh.setRelease(Float.MAX_VALUE);
1297             } catch (WrongMethodTypeException e) {
1298             }
1299             try {
1300                 vh.setRelease(Double.MAX_VALUE);
1301             } catch (WrongMethodTypeException e) {
1302             }
1303             vh.set(null);
1304             vh.set(Integer.valueOf(Integer.MAX_VALUE));
1305         }
1306     }
1307 
main(String[] args)1308     public static void main(String[] args) {
1309         VoidReturnTypeTest.main(args);
1310 
1311         BoxedNullBooleanThrowsNPETest.main(args);
1312         BoxedNullByteThrowsNPETest.main(args);
1313         BoxedNullCharacterThrowsNPETest.main(args);
1314         BoxedNullShortThrowsNPETest.main(args);
1315         BoxedNullIntegerThrowsNPETest.main(args);
1316         BoxedNullLongThrowsNPETest.main(args);
1317         BoxedNullFloatThrowsNPETest.main(args);
1318         BoxedNullDoubleThrowsNPETest.main(args);
1319 
1320         WideningBooleanArgumentTest.main(args);
1321         WideningByteArgumentTest.main(args);
1322         WideningCharacterArgumentTest.main(args);
1323         WideningShortArgumentTest.main(args);
1324         WideningIntegerArgumentTest.main(args);
1325         WideningLongArgumentTest.main(args);
1326         WideningFloatArgumentTest.main(args);
1327         WideningDoubleArgumentTest.main(args);
1328 
1329         WideningBooleanReturnValueTest.main(args);
1330         WideningByteReturnValueTest.main(args);
1331         WideningCharacterReturnValueTest.main(args);
1332         WideningShortReturnValueTest.main(args);
1333         WideningIntegerReturnValueTest.main(args);
1334         WideningLongReturnValueTest.main(args);
1335         WideningFloatReturnValueTest.main(args);
1336         WideningDoubleReturnValueTest.main(args);
1337 
1338         SubtypeTest.main(args);
1339         SupertypeTest.main(args);
1340 
1341         ImplicitBoxingIntegerTest.main(args);
1342     }
1343 }
1344