1/*
2 * Copyright (c) 2010, 2011, 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/**
25 * @test
26 * @bug 6991596
27 * @summary JSR 292 unimplemented adapter_opt_i2i and adapter_opt_l2i on SPARC
28 *
29 * @run main/othervm -ea -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6991596
30 */
31
32import java.lang.invoke.*;
33
34public class Test6991596 {
35    private static final Class   CLASS = Test6991596.class;
36    private static final String  NAME  = "foo";
37    private static final boolean DEBUG = System.getProperty("DEBUG", "false").equals("true");
38
39    public static void main(String[] args) throws Throwable {
40        testboolean();
41        testbyte();
42        testchar();
43        testshort();
44        testint();
45        testlong();
46    }
47
48    // Helpers to get various methods.
49    static MethodHandle getmh1(Class ret, Class arg) throws ReflectiveOperationException {
50        return MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(ret, arg));
51    }
52    static MethodHandle getmh2(MethodHandle mh1, Class ret, Class arg) {
53        return MethodHandles.explicitCastArguments(mh1, MethodType.methodType(ret, arg));
54    }
55    static MethodHandle getmh3(MethodHandle mh1, Class ret, Class arg) {
56        return MethodHandles.explicitCastArguments(mh1, MethodType.methodType(ret, arg));
57    }
58
59    // test adapter_opt_i2i
60    static void testboolean() throws Throwable {
61        boolean[] a = new boolean[] {
62            true,
63            false
64        };
65        for (int i = 0; i < a.length; i++) {
66            doboolean(a[i]);
67        }
68    }
69    static void doboolean(boolean x) throws Throwable {
70        if (DEBUG)  System.out.println("boolean=" + x);
71
72        // boolean
73        {
74            MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
75            MethodHandle mh2 = getmh2(mh1, boolean.class, boolean.class);
76            // TODO add this for all cases when the bugs are fixed.
77            //MethodHandle mh3 = getmh3(mh1, boolean.class, boolean.class);
78            boolean a = (boolean) mh1.invokeExact((boolean) x);
79            boolean b = (boolean) mh2.invokeExact(x);
80            //boolean c = mh3.<boolean>invokeExact((boolean) x);
81            check(x, a, b);
82            //check(x, c, x);
83        }
84
85        // byte
86        {
87            MethodHandle mh1 = getmh1(     byte.class,    byte.class   );
88            MethodHandle mh2 = getmh2(mh1, byte.class,    boolean.class);
89            byte a = (byte) mh1.invokeExact((byte) (x ? 1 : 0));
90            byte b = (byte) mh2.invokeExact(x);
91            check(x, a, b);
92        }
93
94        // char
95        {
96            MethodHandle mh1 = getmh1(     char.class, char.class);
97            MethodHandle mh2 = getmh2(mh1, char.class, boolean.class);
98            char a = (char) mh1.invokeExact((char) (x ? 1 : 0));
99            char b = (char) mh2.invokeExact(x);
100            check(x, a, b);
101        }
102
103        // short
104        {
105            MethodHandle mh1 = getmh1(     short.class, short.class);
106            MethodHandle mh2 = getmh2(mh1, short.class, boolean.class);
107            short a = (short) mh1.invokeExact((short) (x ? 1 : 0));
108            short b = (short) mh2.invokeExact(x);
109            check(x, a, b);
110        }
111    }
112
113    static void testbyte() throws Throwable {
114        byte[] a = new byte[] {
115            Byte.MIN_VALUE,
116            Byte.MIN_VALUE + 1,
117            -0x0F,
118            -1,
119            0,
120            1,
121            0x0F,
122            Byte.MAX_VALUE - 1,
123            Byte.MAX_VALUE
124        };
125        for (int i = 0; i < a.length; i++) {
126            dobyte(a[i]);
127        }
128    }
129    static void dobyte(byte x) throws Throwable {
130        if (DEBUG)  System.out.println("byte=" + x);
131
132        // boolean
133        {
134            MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
135            MethodHandle mh2 = getmh2(mh1, boolean.class, byte.class);
136            boolean a = (boolean) mh1.invokeExact((x & 1) == 1);
137            boolean b = (boolean) mh2.invokeExact(x);
138            check(x, a, b);
139        }
140
141        // byte
142        {
143            MethodHandle mh1 = getmh1(     byte.class, byte.class);
144            MethodHandle mh2 = getmh2(mh1, byte.class, byte.class);
145            byte a = (byte) mh1.invokeExact((byte) x);
146            byte b = (byte) mh2.invokeExact(x);
147            check(x, a, b);
148        }
149
150        // char
151        {
152            MethodHandle mh1 = getmh1(     char.class, char.class);
153            MethodHandle mh2 = getmh2(mh1, char.class, byte.class);
154            char a = (char) mh1.invokeExact((char) x);
155            char b = (char) mh2.invokeExact(x);
156            check(x, a, b);
157        }
158
159        // short
160        {
161            MethodHandle mh1 = getmh1(     short.class, short.class);
162            MethodHandle mh2 = getmh2(mh1, short.class, byte.class);
163            short a = (short) mh1.invokeExact((short) x);
164            short b = (short) mh2.invokeExact(x);
165            check(x, a, b);
166        }
167    }
168
169    static void testchar() throws Throwable {
170        char[] a = new char[] {
171            Character.MIN_VALUE,
172            Character.MIN_VALUE + 1,
173            0x000F,
174            0x00FF,
175            0x0FFF,
176            Character.MAX_VALUE - 1,
177            Character.MAX_VALUE
178        };
179        for (int i = 0; i < a.length; i++) {
180            dochar(a[i]);
181        }
182    }
183    static void dochar(char x) throws Throwable {
184        if (DEBUG)  System.out.println("char=" + x);
185
186        // boolean
187        {
188            MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
189            MethodHandle mh2 = getmh2(mh1, boolean.class, char.class);
190            boolean a = (boolean) mh1.invokeExact((x & 1) == 1);
191            boolean b = (boolean) mh2.invokeExact(x);
192            check(x, a, b);
193        }
194
195        // byte
196        {
197            MethodHandle mh1 = getmh1(     byte.class, byte.class);
198            MethodHandle mh2 = getmh2(mh1, byte.class, char.class);
199            byte a = (byte) mh1.invokeExact((byte) x);
200            byte b = (byte) mh2.invokeExact(x);
201            check(x, a, b);
202        }
203
204        // char
205        {
206            MethodHandle mh1 = getmh1(     char.class, char.class);
207            MethodHandle mh2 = getmh2(mh1, char.class, char.class);
208            char a = (char) mh1.invokeExact((char) x);
209            char b = (char) mh2.invokeExact(x);
210            check(x, a, b);
211        }
212
213        // short
214        {
215            MethodHandle mh1 = getmh1(     short.class, short.class);
216            MethodHandle mh2 = getmh2(mh1, short.class, char.class);
217            short a = (short) mh1.invokeExact((short) x);
218            short b = (short) mh2.invokeExact(x);
219            check(x, a, b);
220        }
221    }
222
223    static void testshort() throws Throwable {
224        short[] a = new short[] {
225            Short.MIN_VALUE,
226            Short.MIN_VALUE + 1,
227            -0x0FFF,
228            -0x00FF,
229            -0x000F,
230            -1,
231            0,
232            1,
233            0x000F,
234            0x00FF,
235            0x0FFF,
236            Short.MAX_VALUE - 1,
237            Short.MAX_VALUE
238        };
239        for (int i = 0; i < a.length; i++) {
240            doshort(a[i]);
241        }
242    }
243    static void doshort(short x) throws Throwable {
244        if (DEBUG)  System.out.println("short=" + x);
245
246        // boolean
247        {
248            MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
249            MethodHandle mh2 = getmh2(mh1, boolean.class, short.class);
250            boolean a = (boolean) mh1.invokeExact((x & 1) == 1);
251            boolean b = (boolean) mh2.invokeExact(x);
252            check(x, a, b);
253        }
254
255        // byte
256        {
257            MethodHandle mh1 = getmh1(     byte.class, byte.class);
258            MethodHandle mh2 = getmh2(mh1, byte.class, short.class);
259            byte a = (byte) mh1.invokeExact((byte) x);
260            byte b = (byte) mh2.invokeExact(x);
261            check(x, a, b);
262        }
263
264        // char
265        {
266            MethodHandle mh1 = getmh1(     char.class, char.class);
267            MethodHandle mh2 = getmh2(mh1, char.class, short.class);
268            char a = (char) mh1.invokeExact((char) x);
269            char b = (char) mh2.invokeExact(x);
270            check(x, a, b);
271        }
272
273        // short
274        {
275            MethodHandle mh1 = getmh1(     short.class, short.class);
276            MethodHandle mh2 = getmh2(mh1, short.class, short.class);
277            short a = (short) mh1.invokeExact((short) x);
278            short b = (short) mh2.invokeExact(x);
279            check(x, a, b);
280        }
281    }
282
283    static void testint() throws Throwable {
284        int[] a = new int[] {
285            Integer.MIN_VALUE,
286            Integer.MIN_VALUE + 1,
287            -0x0FFFFFFF,
288            -0x00FFFFFF,
289            -0x000FFFFF,
290            -0x0000FFFF,
291            -0x00000FFF,
292            -0x000000FF,
293            -0x0000000F,
294            -1,
295            0,
296            1,
297            0x0000000F,
298            0x000000FF,
299            0x00000FFF,
300            0x0000FFFF,
301            0x000FFFFF,
302            0x00FFFFFF,
303            0x0FFFFFFF,
304            Integer.MAX_VALUE - 1,
305            Integer.MAX_VALUE
306        };
307        for (int i = 0; i < a.length; i++) {
308            doint(a[i]);
309        }
310    }
311    static void doint(int x) throws Throwable {
312        if (DEBUG)  System.out.println("int=" + x);
313
314        // boolean
315        {
316            MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
317            MethodHandle mh2 = getmh2(mh1, boolean.class, int.class);
318            boolean a = (boolean) mh1.invokeExact((x & 1) == 1);
319            boolean b = (boolean) mh2.invokeExact(x);
320            check(x, a, b);
321        }
322
323        // byte
324        {
325            MethodHandle mh1 = getmh1(     byte.class, byte.class);
326            MethodHandle mh2 = getmh2(mh1, byte.class, int.class);
327            byte a = (byte) mh1.invokeExact((byte) x);
328            byte b = (byte) mh2.invokeExact(x);
329            check(x, a, b);
330        }
331
332        // char
333        {
334            MethodHandle mh1 = getmh1(     char.class, char.class);
335            MethodHandle mh2 = getmh2(mh1, char.class, int.class);
336            char a = (char) mh1.invokeExact((char) x);
337            char b = (char) mh2.invokeExact(x);
338            check(x, a, b);
339        }
340
341        // short
342        {
343            MethodHandle mh1 = getmh1(     short.class, short.class);
344            MethodHandle mh2 = getmh2(mh1, short.class, int.class);
345            short a = (short) mh1.invokeExact((short) x);
346            short b = (short) mh2.invokeExact(x);
347            assert a == b : a + " != " + b;
348            check(x, a, b);
349        }
350
351        // int
352        {
353            MethodHandle mh1 = getmh1(     int.class, int.class);
354            MethodHandle mh2 = getmh2(mh1, int.class, int.class);
355            int a = (int) mh1.invokeExact((int) x);
356            int b = (int) mh2.invokeExact(x);
357            check(x, a, b);
358        }
359    }
360
361    // test adapter_opt_l2i
362    static void testlong() throws Throwable {
363        long[] a = new long[] {
364            Long.MIN_VALUE,
365            Long.MIN_VALUE + 1,
366            -0x000000000FFFFFFFL,
367            -0x0000000000FFFFFFL,
368            -0x00000000000FFFFFL,
369            -0x000000000000FFFFL,
370            -0x0000000000000FFFL,
371            -0x00000000000000FFL,
372            -0x000000000000000FL,
373            -1L,
374            0L,
375            1L,
376            0x000000000000000FL,
377            0x00000000000000FFL,
378            0x0000000000000FFFL,
379            0x0000000000000FFFL,
380            0x000000000000FFFFL,
381            0x00000000000FFFFFL,
382            0x0000000000FFFFFFL,
383            0x000000000FFFFFFFL,
384            Long.MAX_VALUE - 1,
385            Long.MAX_VALUE
386        };
387        for (int i = 0; i < a.length; i++) {
388            dolong(a[i]);
389        }
390    }
391    static void dolong(long x) throws Throwable {
392        if (DEBUG)  System.out.println("long=" + x);
393
394        // boolean
395        {
396            MethodHandle mh1 = getmh1(     boolean.class, boolean.class);
397            MethodHandle mh2 = getmh2(mh1, boolean.class, long.class);
398            boolean a = (boolean) mh1.invokeExact((x & 1L) == 1L);
399            boolean b = (boolean) mh2.invokeExact(x);
400            check(x, a, b);
401        }
402
403        // byte
404        {
405            MethodHandle mh1 = getmh1(     byte.class, byte.class);
406            MethodHandle mh2 = getmh2(mh1, byte.class, long.class);
407            byte a = (byte) mh1.invokeExact((byte) x);
408            byte b = (byte) mh2.invokeExact(x);
409            check(x, a, b);
410        }
411
412        // char
413        {
414            MethodHandle mh1 = getmh1(     char.class, char.class);
415            MethodHandle mh2 = getmh2(mh1, char.class, long.class);
416            char a = (char) mh1.invokeExact((char) x);
417            char b = (char) mh2.invokeExact(x);
418            check(x, a, b);
419        }
420
421        // short
422        {
423            MethodHandle mh1 = getmh1(     short.class, short.class);
424            MethodHandle mh2 = getmh2(mh1, short.class, long.class);
425            short a = (short) mh1.invokeExact((short) x);
426            short b = (short) mh2.invokeExact(x);
427            check(x, a, b);
428        }
429
430        // int
431        {
432            MethodHandle mh1 = getmh1(     int.class, int.class);
433            MethodHandle mh2 = getmh2(mh1, int.class, long.class);
434            int a = (int) mh1.invokeExact((int) x);
435            int b = (int) mh2.invokeExact(x);
436            check(x, a, b);
437        }
438    }
439
440    static void check(boolean x, boolean e, boolean a) { p(z2h(x), z2h(e), z2h(a)); assert e == a : z2h(x) + ": " + z2h(e) + " != " + z2h(a); }
441    static void check(boolean x, byte    e, byte    a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); }
442    static void check(boolean x, int     e, int     a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); }
443
444    static void check(int     x, boolean e, boolean a) { p(i2h(x), z2h(e), z2h(a)); assert e == a : i2h(x) + ": " + z2h(e) + " != " + z2h(a); }
445    static void check(int     x, byte    e, byte    a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); }
446    static void check(int     x, int     e, int     a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); }
447
448    static void check(long    x, boolean e, boolean a) { p(l2h(x), z2h(e), z2h(a)); assert e == a : l2h(x) + ": " + z2h(e) + " != " + z2h(a); }
449    static void check(long    x, byte    e, byte    a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); }
450    static void check(long    x, int     e, int     a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); }
451
452    static void p(String x, String e, String a) { if (DEBUG)  System.out.println(x + ": expected: " + e + ", actual: " + a); }
453
454    static String z2h(boolean x) { return x ? "1" : "0"; }
455    static String i2h(int     x) { return Integer.toHexString(x); }
456    static String l2h(long    x) { return Long.toHexString(x); }
457
458    // to int
459    public static boolean foo(boolean i) { return i; }
460    public static byte    foo(byte    i) { return i; }
461    public static char    foo(char    i) { return i; }
462    public static short   foo(short   i) { return i; }
463    public static int     foo(int     i) { return i; }
464}
465