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 
  32 import java.lang.invoke.*;
  33 
  34 public 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 }