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