Test6998541.java revision 4183:4732a76af216
1189251Ssam/* 2189251Ssam * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 3189251Ssam * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4189251Ssam * 5252726Srpaulo * This code is free software; you can redistribute it and/or modify it 6252726Srpaulo * under the terms of the GNU General Public License version 2 only, as 7189251Ssam * published by the Free Software Foundation. 8189251Ssam * 9189251Ssam * This code is distributed in the hope that it will be useful, but WITHOUT 10189251Ssam * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11189251Ssam * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12214734Srpaulo * version 2 for more details (a copy is included in the LICENSE file that 13214734Srpaulo * accompanied this code). 14214734Srpaulo * 15214734Srpaulo * You should have received a copy of the GNU General Public License version 16214734Srpaulo * 2 along with this work; if not, write to the Free Software Foundation, 17252726Srpaulo * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18189251Ssam * 19189251Ssam * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20189251Ssam * or visit www.oracle.com if you need additional information or have any 21189251Ssam * questions. 22189251Ssam * 23189251Ssam */ 24189251Ssam 25189251Ssam/** 26189251Ssam * @test 27189251Ssam * @bug 6998541 28189251Ssam * @summary JSR 292 implement missing return-type conversion for OP_RETYPE_RAW 29189251Ssam * 30189251Ssam * @run main/othervm -Xbatch 31189251Ssam * -XX:+UnlockDiagnosticVMOptions -XX:ScavengeRootsInCode=2 32189251Ssam * -DTest6998541.N=100000 -DTest6998541.KIND=cast Test6998541 33189251Ssam * @run main/othervm -Xbatch 34189251Ssam * -XX:+UnlockDiagnosticVMOptions -XX:ScavengeRootsInCode=2 35189251Ssam * -DTest6998541.N=100000 -DTest6998541.KIND=normal Test6998541 36189251Ssam */ 37189251Ssam 38189251Ssamimport java.util.*; 39189251Ssam 40189251Ssamimport java.lang.invoke.*; 41189251Ssamimport static java.lang.invoke.MethodHandles.*; 42189251Ssam 43189251Ssampublic class Test6998541 { 44189251Ssam private static final Class CLASS = Test6998541.class; 45189251Ssam private static final String NAME = "identity"; 46189251Ssam private static final int N = Math.max(2, Integer.getInteger(CLASS.getSimpleName()+".N", 10000)); 47189251Ssam private static final String KIND = System.getProperty(CLASS.getSimpleName()+".KIND", "cast"); 48189251Ssam private static final int BITS = 0x00000201; 49189251Ssam 50189251Ssam private static final boolean DO_CASTS = !KIND.equals("normal"); 51189251Ssam 52189251Ssam public static void main(String[] args) throws Throwable { 53189251Ssam System.out.println("KIND="+KIND+" DO_CASTS="+DO_CASTS+" N="+N); 54189251Ssam doboolean(); 55189251Ssam dobyte(); 56189251Ssam dochar(); 57189251Ssam doshort(); 58189251Ssam doint(); 59189251Ssam dolong(); 60189251Ssam dofloat(); 61189251Ssam dodouble(); 62189251Ssam dovoid(); 63189251Ssam } 64189251Ssam 65189251Ssam private static void doboolean() throws Throwable { 66189251Ssam for (int i = 0; i < N; i++) { 67189251Ssam boolean2prim(false); 68189251Ssam boolean2prim(true); 69189251Ssam } 70189251Ssam boolean2prim_invalid(true); 71189251Ssam } 72189251Ssam private static void dobyte() throws Throwable { 73189251Ssam byte x = Byte.MIN_VALUE; 74189251Ssam for (int i = 0; i < N; i++, x++) 75189251Ssam byte2prim(x); 76189251Ssam byte2prim_invalid(x); 77189251Ssam } 78189251Ssam private static void dochar() throws Throwable { 79189251Ssam char x = Character.MIN_VALUE; 80189251Ssam for (int i = 0; i < N; i++, x++) 81189251Ssam char2prim(x); 82189251Ssam char2prim_invalid(x); 83189251Ssam } 84189251Ssam private static void doshort() throws Throwable { 85189251Ssam short x = Short.MIN_VALUE; 86189251Ssam for (int i = 0; i < N; i++, x++) 87189251Ssam short2prim(x); 88189251Ssam short2prim_invalid(x); 89189251Ssam } 90189251Ssam private static void doint() throws Throwable { 91189251Ssam int x = Integer.MIN_VALUE; 92189251Ssam int D = Integer.MAX_VALUE / (N / 2) | BITS; 93189251Ssam for (int i = 0; i < N; i++, x += D) { 94189251Ssam int2prim(x); 95189251Ssam } 96189251Ssam int2prim_invalid(x); 97189251Ssam } 98189251Ssam private static void dolong() throws Throwable { 99189251Ssam long x = Long.MIN_VALUE; 100189251Ssam long D = Long.MAX_VALUE / ((long) (N / 2)) | BITS; 101189251Ssam for (int i = 0; i < N; i++, x += D) 102189251Ssam long2prim(x); 103189251Ssam long2prim_invalid(x); 104189251Ssam } 105189251Ssam private static void dofloat() throws Throwable { 106189251Ssam float x = Float.MIN_VALUE; 107189251Ssam float D = Float.MAX_VALUE / ((float) (N / 2)); 108189251Ssam for (int i = 0; i < N; i++, x += D) 109189251Ssam float2prim(x); 110189251Ssam float2prim_invalid(x); 111189251Ssam } 112189251Ssam private static void dodouble() throws Throwable { 113189251Ssam double x = Double.MIN_VALUE; 114189251Ssam double D = Double.MAX_VALUE / ((double) (N / 2)); 115189251Ssam for (int i = 0; i < N; i++, x += D) 116189251Ssam double2prim(x); 117189251Ssam double2prim_invalid(x); 118189251Ssam } 119189251Ssam private static void dovoid() throws Throwable { 120189251Ssam for (int i = 0; i < N; i++) { 121189251Ssam void2prim(i); 122189251Ssam } 123189251Ssam void2prim_invalid(0); 124189251Ssam // do the other direction here also: 125189251Ssam for (int i = 0; i < N; i++) { 126189251Ssam prim2void(i); 127189251Ssam } 128189251Ssam prim2void_invalid(0); 129189251Ssam } 130189251Ssam 131189251Ssam private static void assertEquals(Object o, Object o2) { 132189251Ssam if (!o.equals(o2)) 133189251Ssam throw new AssertionError("expected: " + o + ", found: " + o2); 134189251Ssam } 135189251Ssam private static void fail() { 136189251Ssam throw new AssertionError(); 137189251Ssam } 138189251Ssam 139189251Ssam private final static MethodHandles.Lookup lookup = MethodHandles.lookup(); 140189251Ssam 141189251Ssam private static MethodHandle mh(Class ret, Class... args) { 142189251Ssam try { 143189251Ssam MethodType mt = MethodType.methodType(ret, args); 144189251Ssam Class lookupRet = (args.length == 0 ? void.class : args[0]); 145189251Ssam MethodHandle mh = lookup.findStatic(CLASS, NAME, mt.changeReturnType(lookupRet)); 146189251Ssam if (DO_CASTS) 147189251Ssam return MethodHandles.explicitCastArguments(mh, mt); 148189251Ssam if (canDoAsType(mh.type(), mt)) 149189251Ssam return mh.asType(mt); 150189251Ssam try { 151189251Ssam mh.asType(mt); 152189251Ssam throw new AssertionError("asType should not succeed: "+mh+" => "+mt); 153189251Ssam } catch (WrongMethodTypeException ex) { 154189251Ssam // this was a required WMTE 155189251Ssam return mh.asType(mt.generic()).asType(mt); 156189251Ssam } 157189251Ssam } catch (ReflectiveOperationException e) { 158189251Ssam throw new RuntimeException(e); 159189251Ssam } 160189251Ssam } 161189251Ssam private static final Class<?>[] NUMERIC_TYPE_WIDENING_ORDER = { 162189251Ssam byte.class, short.class, int.class, long.class, float.class, double.class 163189251Ssam }; 164189251Ssam private static boolean canDoAsType(Class<?> src, Class<?> dst) { 165189251Ssam if (src == dst) return true; 166189251Ssam if (dst == void.class) return true; 167189251Ssam if (!src.isPrimitive() || !dst.isPrimitive()) return true; 168189251Ssam // primitive conversion works for asType only when it's widening 169189251Ssam if (src == boolean.class || dst == boolean.class) return false; 170189251Ssam if (dst == char.class) return false; 171189251Ssam if (src == char.class) src = int.class; // can widen char to int 172189251Ssam for (Class<?> ntype : NUMERIC_TYPE_WIDENING_ORDER) { 173189251Ssam if (src == ntype) return true; 174189251Ssam if (dst == ntype) return false; 175189251Ssam } 176189251Ssam throw new AssertionError("should not reach here: "+src+", "+dst); 177189251Ssam } 178189251Ssam private static boolean canDoAsType(MethodType mt0, MethodType mt1) { 179189251Ssam Class<?> rt0 = mt0.returnType(); 180189251Ssam Class<?> rt1 = mt1.returnType(); 181189251Ssam if (!canDoAsType(rt0, rt1)) return false; 182189251Ssam int argc = mt0.parameterCount(); 183189251Ssam if (argc != mt1.parameterCount()) return false; 184189251Ssam for (int i = 0; i < argc; i++) { 185189251Ssam if (!canDoAsType(mt1.parameterType(i), mt0.parameterType(i))) 186189251Ssam return false; 187189251Ssam } 188189251Ssam return true; 189189251Ssam } 190189251Ssam 191189251Ssam private static MethodHandle mh_z(Class ret) { return mh(ret, boolean.class); } 192189251Ssam 193189251Ssam private final static MethodHandle mh_zz = mh_z(boolean.class); 194189251Ssam private final static MethodHandle mh_bz = mh_z(byte.class ); 195189251Ssam private final static MethodHandle mh_cz = mh_z(char.class ); 196189251Ssam private final static MethodHandle mh_sz = mh_z(short.class ); 197189251Ssam private final static MethodHandle mh_iz = mh_z(int.class ); 198189251Ssam private final static MethodHandle mh_jz = mh_z(long.class ); 199189251Ssam private final static MethodHandle mh_fz = mh_z(float.class ); 200189251Ssam private final static MethodHandle mh_dz = mh_z(double.class ); 201189251Ssam 202189251Ssam private static void boolean2prim(boolean x) throws Throwable { 203189251Ssam int i = x ? 1 : 0; 204189251Ssam assertEquals( x, (boolean) mh_zz.invokeExact(x)); // boolean -> boolean 205189251Ssam if (!DO_CASTS) return; 206189251Ssam assertEquals((byte) i, (byte) mh_bz.invokeExact(x)); // boolean -> byte 207189251Ssam assertEquals((char) i, (char) mh_cz.invokeExact(x)); // boolean -> char 208189251Ssam assertEquals((short) i, (short) mh_sz.invokeExact(x)); // boolean -> short 209189251Ssam assertEquals((int) i, (int) mh_iz.invokeExact(x)); // boolean -> int 210189251Ssam assertEquals((long) i, (long) mh_jz.invokeExact(x)); // boolean -> long 211189251Ssam assertEquals((float) i, (float) mh_fz.invokeExact(x)); // boolean -> float 212189251Ssam assertEquals((double) i, (double) mh_dz.invokeExact(x)); // boolean -> double 213189251Ssam } 214189251Ssam private static void boolean2prim_invalid(boolean x) throws Throwable { 215189251Ssam if (DO_CASTS) return; 216189251Ssam try { byte y = (byte) mh_bz.invokeExact(x); fail(); } catch (ClassCastException _) {} // boolean -> byte 217189251Ssam try { char y = (char) mh_cz.invokeExact(x); fail(); } catch (ClassCastException _) {} // boolean -> char 218189251Ssam try { short y = (short) mh_sz.invokeExact(x); fail(); } catch (ClassCastException _) {} // boolean -> short 219189251Ssam try { int y = (int) mh_iz.invokeExact(x); fail(); } catch (ClassCastException _) {} // boolean -> int 220189251Ssam try { long y = (long) mh_jz.invokeExact(x); fail(); } catch (ClassCastException _) {} // boolean -> long 221189251Ssam try { float y = (float) mh_fz.invokeExact(x); fail(); } catch (ClassCastException _) {} // boolean -> float 222189251Ssam try { double y = (double) mh_dz.invokeExact(x); fail(); } catch (ClassCastException _) {} // boolean -> double 223189251Ssam } 224189251Ssam 225189251Ssam private static MethodHandle mh_b(Class ret) { return mh(ret, byte.class); } 226189251Ssam 227189251Ssam private final static MethodHandle mh_zb = mh_b(boolean.class); 228189251Ssam private final static MethodHandle mh_bb = mh_b(byte.class ); 229189251Ssam private final static MethodHandle mh_cb = mh_b(char.class ); 230189251Ssam private final static MethodHandle mh_sb = mh_b(short.class ); 231214734Srpaulo private final static MethodHandle mh_ib = mh_b(int.class ); 232189251Ssam private final static MethodHandle mh_jb = mh_b(long.class ); 233189251Ssam private final static MethodHandle mh_fb = mh_b(float.class ); 234189251Ssam private final static MethodHandle mh_db = mh_b(double.class ); 235189251Ssam 236189251Ssam private static void byte2prim(byte x) throws Throwable { 237189251Ssam assertEquals((byte) x, (byte) mh_bb.invokeExact(x)); // byte -> byte 238189251Ssam assertEquals((short) x, (short) mh_sb.invokeExact(x)); // byte -> short 239189251Ssam assertEquals((int) x, (int) mh_ib.invokeExact(x)); // byte -> int 240189251Ssam assertEquals((long) x, (long) mh_jb.invokeExact(x)); // byte -> long 241189251Ssam assertEquals((float) x, (float) mh_fb.invokeExact(x)); // byte -> float 242189251Ssam assertEquals((double) x, (double) mh_db.invokeExact(x)); // byte -> double 243189251Ssam if (!DO_CASTS) return; 244189251Ssam boolean z = ((x & 1) != 0); 245189251Ssam assertEquals((char) x, (char) mh_cb.invokeExact(x)); // byte -> char 246189251Ssam assertEquals((boolean) z, (boolean) mh_zb.invokeExact(x)); // byte -> boolean 247189251Ssam } 248189251Ssam private static void byte2prim_invalid(byte x) throws Throwable { 249189251Ssam if (DO_CASTS) return; 250189251Ssam try { char y = (char) mh_cb.invokeExact(x); fail(); } catch (ClassCastException _) {} // byte -> char 251189251Ssam try { boolean y = (boolean) mh_zb.invokeExact(x); fail(); } catch (ClassCastException _) {} // byte -> boolean 252189251Ssam } 253189251Ssam 254189251Ssam private static MethodHandle mh_c(Class ret) { return mh(ret, char.class); } 255189251Ssam 256189251Ssam private final static MethodHandle mh_zc = mh_c(boolean.class); 257189251Ssam private final static MethodHandle mh_bc = mh_c(byte.class ); 258189251Ssam private final static MethodHandle mh_cc = mh_c(char.class ); 259189251Ssam private final static MethodHandle mh_sc = mh_c(short.class ); 260189251Ssam private final static MethodHandle mh_ic = mh_c(int.class ); 261189251Ssam private final static MethodHandle mh_jc = mh_c(long.class ); 262189251Ssam private final static MethodHandle mh_fc = mh_c(float.class ); 263189251Ssam private final static MethodHandle mh_dc = mh_c(double.class ); 264189251Ssam 265189251Ssam private static void char2prim(char x) throws Throwable { 266189251Ssam assertEquals((char) x, (char) mh_cc.invokeExact(x)); // char -> char 267189251Ssam assertEquals((int) x, (int) mh_ic.invokeExact(x)); // char -> int 268189251Ssam assertEquals((long) x, (long) mh_jc.invokeExact(x)); // char -> long 269189251Ssam assertEquals((float) x, (float) mh_fc.invokeExact(x)); // char -> float 270189251Ssam assertEquals((double) x, (double) mh_dc.invokeExact(x)); // char -> double 271189251Ssam if (!DO_CASTS) return; 272189251Ssam boolean z = ((x & 1) != 0); 273189251Ssam assertEquals((boolean) z, (boolean) mh_zc.invokeExact(x)); // char -> boolean 274189251Ssam assertEquals((byte) x, (byte) mh_bc.invokeExact(x)); // char -> byte 275189251Ssam assertEquals((short) x, (short) mh_sc.invokeExact(x)); // char -> short 276189251Ssam } 277189251Ssam private static void char2prim_invalid(char x) throws Throwable { 278189251Ssam if (DO_CASTS) return; 279189251Ssam try { boolean y = (boolean) mh_zc.invokeExact(x); fail(); } catch (ClassCastException _) {} // char -> boolean 280189251Ssam try { byte y = (byte) mh_bc.invokeExact(x); fail(); } catch (ClassCastException _) {} // char -> byte 281189251Ssam try { short y = (short) mh_sc.invokeExact(x); fail(); } catch (ClassCastException _) {} // char -> short 282189251Ssam } 283189251Ssam 284189251Ssam private static MethodHandle mh_s(Class ret) { return mh(ret, short.class); } 285189251Ssam 286189251Ssam private final static MethodHandle mh_zs = mh_s(boolean.class); 287189251Ssam private final static MethodHandle mh_bs = mh_s(byte.class ); 288189251Ssam private final static MethodHandle mh_cs = mh_s(char.class ); 289189251Ssam private final static MethodHandle mh_ss = mh_s(short.class ); 290189251Ssam private final static MethodHandle mh_is = mh_s(int.class ); 291189251Ssam private final static MethodHandle mh_js = mh_s(long.class ); 292189251Ssam private final static MethodHandle mh_fs = mh_s(float.class ); 293189251Ssam private final static MethodHandle mh_ds = mh_s(double.class ); 294189251Ssam 295189251Ssam private static void short2prim(short x) throws Throwable { 296189251Ssam assertEquals((short) x, (short) mh_ss.invokeExact(x)); // short -> short 297189251Ssam assertEquals((int) x, (int) mh_is.invokeExact(x)); // short -> int 298189251Ssam assertEquals((long) x, (long) mh_js.invokeExact(x)); // short -> long 299189251Ssam assertEquals((float) x, (float) mh_fs.invokeExact(x)); // short -> float 300189251Ssam assertEquals((double) x, (double) mh_ds.invokeExact(x)); // short -> double 301189251Ssam if (!DO_CASTS) return; 302189251Ssam boolean z = ((x & 1) != 0); 303189251Ssam assertEquals((boolean) z, (boolean) mh_zs.invokeExact(x)); // short -> boolean 304189251Ssam assertEquals((byte) x, (byte) mh_bs.invokeExact(x)); // short -> byte 305189251Ssam assertEquals((char) x, (char) mh_cs.invokeExact(x)); // short -> char 306189251Ssam } 307189251Ssam private static void short2prim_invalid(short x) throws Throwable { 308189251Ssam if (DO_CASTS) return; 309189251Ssam try { boolean y = (boolean) mh_zs.invokeExact(x); fail(); } catch (ClassCastException _) {} // short -> boolean 310189251Ssam try { byte y = (byte) mh_bs.invokeExact(x); fail(); } catch (ClassCastException _) {} // short -> byte 311189251Ssam try { char y = (char) mh_cs.invokeExact(x); fail(); } catch (ClassCastException _) {} // short -> char 312189251Ssam } 313189251Ssam 314189251Ssam private static MethodHandle mh_i(Class ret) { return mh(ret, int.class); } 315189251Ssam 316189251Ssam private final static MethodHandle mh_zi = mh_i(boolean.class); 317189251Ssam private final static MethodHandle mh_bi = mh_i(byte.class ); 318189251Ssam private final static MethodHandle mh_ci = mh_i(char.class ); 319189251Ssam private final static MethodHandle mh_si = mh_i(short.class ); 320189251Ssam private final static MethodHandle mh_ii = mh_i(int.class ); 321189251Ssam private final static MethodHandle mh_ji = mh_i(long.class ); 322189251Ssam private final static MethodHandle mh_fi = mh_i(float.class ); 323189251Ssam private final static MethodHandle mh_di = mh_i(double.class ); 324189251Ssam 325189251Ssam private static void int2prim(int x) throws Throwable { 326189251Ssam assertEquals((int) x, (int) mh_ii.invokeExact(x)); // int -> int 327189251Ssam assertEquals((long) x, (long) mh_ji.invokeExact(x)); // int -> long 328189251Ssam assertEquals((float) x, (float) mh_fi.invokeExact(x)); // int -> float 329189251Ssam assertEquals((double) x, (double) mh_di.invokeExact(x)); // int -> double 330189251Ssam if (!DO_CASTS) return; 331189251Ssam boolean z = ((x & 1) != 0); 332189251Ssam assertEquals((boolean) z, (boolean) mh_zi.invokeExact(x)); // int -> boolean 333189251Ssam assertEquals((byte) x, (byte) mh_bi.invokeExact(x)); // int -> byte 334189251Ssam assertEquals((char) x, (char) mh_ci.invokeExact(x)); // int -> char 335189251Ssam assertEquals((short) x, (short) mh_si.invokeExact(x)); // int -> short 336189251Ssam } 337189251Ssam private static void int2prim_invalid(int x) throws Throwable { 338189251Ssam if (DO_CASTS) return; 339189251Ssam try { boolean y = (boolean) mh_zi.invokeExact(x); fail(); } catch (ClassCastException _) {} // int -> boolean 340189251Ssam try { byte y = (byte) mh_bi.invokeExact(x); fail(); } catch (ClassCastException _) {} // int -> byte 341189251Ssam try { char y = (char) mh_ci.invokeExact(x); fail(); } catch (ClassCastException _) {} // int -> char 342189251Ssam try { short y = (short) mh_si.invokeExact(x); fail(); } catch (ClassCastException _) {} // int -> short 343189251Ssam } 344189251Ssam 345189251Ssam private static MethodHandle mh_j(Class ret) { return mh(ret, long.class); } 346189251Ssam 347189251Ssam private final static MethodHandle mh_zj = mh_j(boolean.class); 348189251Ssam private final static MethodHandle mh_bj = mh_j(byte.class ); 349189251Ssam private final static MethodHandle mh_cj = mh_j(char.class ); 350189251Ssam private final static MethodHandle mh_sj = mh_j(short.class ); 351189251Ssam private final static MethodHandle mh_ij = mh_j(int.class ); 352189251Ssam private final static MethodHandle mh_jj = mh_j(long.class ); 353189251Ssam private final static MethodHandle mh_fj = mh_j(float.class ); 354189251Ssam private final static MethodHandle mh_dj = mh_j(double.class ); 355189251Ssam 356189251Ssam private static void long2prim(long x) throws Throwable { 357189251Ssam assertEquals((long) x, (long) mh_jj.invokeExact(x)); // long -> long 358189251Ssam assertEquals((float) x, (float) mh_fj.invokeExact(x)); // long -> float 359189251Ssam assertEquals((double) x, (double) mh_dj.invokeExact(x)); // long -> double 360189251Ssam if (!DO_CASTS) return; 361189251Ssam boolean z = ((x & 1) != 0); 362189251Ssam assertEquals((boolean)z, (boolean) mh_zj.invokeExact(x)); // long -> boolean 363189251Ssam assertEquals((byte) x, (byte) mh_bj.invokeExact(x)); // long -> byte 364189251Ssam assertEquals((char) x, (char) mh_cj.invokeExact(x)); // long -> char 365189251Ssam assertEquals((short) x, (short) mh_sj.invokeExact(x)); // long -> short 366189251Ssam assertEquals((int) x, (int) mh_ij.invokeExact(x)); // long -> int 367189251Ssam } 368189251Ssam private static void long2prim_invalid(long x) throws Throwable { 369189251Ssam if (DO_CASTS) return; 370189251Ssam try { boolean y = (boolean) mh_zj.invokeExact(x); fail(); } catch (ClassCastException _) {} // long -> boolean 371189251Ssam try { byte y = (byte) mh_bj.invokeExact(x); fail(); } catch (ClassCastException _) {} // long -> byte 372189251Ssam try { char y = (char) mh_cj.invokeExact(x); fail(); } catch (ClassCastException _) {} // long -> char 373189251Ssam try { short y = (short) mh_sj.invokeExact(x); fail(); } catch (ClassCastException _) {} // long -> short 374189251Ssam try { int y = (int) mh_ij.invokeExact(x); fail(); } catch (ClassCastException _) {} // long -> int 375189251Ssam } 376189251Ssam 377189251Ssam private static MethodHandle mh_f(Class ret) { return mh(ret, float.class); } 378189251Ssam 379189251Ssam private final static MethodHandle mh_zf = mh_f(boolean.class); 380189251Ssam private final static MethodHandle mh_bf = mh_f(byte.class ); 381189251Ssam private final static MethodHandle mh_cf = mh_f(char.class ); 382189251Ssam private final static MethodHandle mh_sf = mh_f(short.class ); 383189251Ssam private final static MethodHandle mh_if = mh_f(int.class ); 384189251Ssam private final static MethodHandle mh_jf = mh_f(long.class ); 385189251Ssam private final static MethodHandle mh_ff = mh_f(float.class ); 386189251Ssam private final static MethodHandle mh_df = mh_f(double.class ); 387189251Ssam 388189251Ssam private static void float2prim(float x) throws Throwable { 389189251Ssam assertEquals((float) x, (float) mh_ff.invokeExact(x)); // float -> float 390189251Ssam assertEquals((double) x, (double) mh_df.invokeExact(x)); // float -> double 391189251Ssam if (!DO_CASTS) return; 392189251Ssam boolean z = (((byte) x & 1) != 0); 393189251Ssam assertEquals((boolean) z, (boolean) mh_zf.invokeExact(x)); // float -> boolean 394189251Ssam assertEquals((byte) x, (byte) mh_bf.invokeExact(x)); // float -> byte 395189251Ssam assertEquals((char) x, (char) mh_cf.invokeExact(x)); // float -> char 396189251Ssam assertEquals((short) x, (short) mh_sf.invokeExact(x)); // float -> short 397189251Ssam assertEquals((int) x, (int) mh_if.invokeExact(x)); // float -> int 398189251Ssam assertEquals((long) x, (long) mh_jf.invokeExact(x)); // float -> long 399189251Ssam } 400189251Ssam private static void float2prim_invalid(float x) throws Throwable { 401189251Ssam if (DO_CASTS) return; 402189251Ssam try { boolean y = (boolean) mh_zf.invokeExact(x); fail(); } catch (ClassCastException _) {} // float -> boolean 403189251Ssam try { byte y = (byte) mh_bf.invokeExact(x); fail(); } catch (ClassCastException _) {} // float -> byte 404189251Ssam try { char y = (char) mh_cf.invokeExact(x); fail(); } catch (ClassCastException _) {} // float -> char 405189251Ssam try { short y = (short) mh_sf.invokeExact(x); fail(); } catch (ClassCastException _) {} // float -> short 406189251Ssam try { int y = (int) mh_if.invokeExact(x); fail(); } catch (ClassCastException _) {} // float -> int 407189251Ssam try { long y = (long) mh_jf.invokeExact(x); fail(); } catch (ClassCastException _) {} // float -> long 408189251Ssam } 409189251Ssam 410189251Ssam private static MethodHandle mh_d(Class ret) { return mh(ret, double.class); } 411189251Ssam 412189251Ssam private final static MethodHandle mh_zd = mh_d(boolean.class); 413189251Ssam private final static MethodHandle mh_bd = mh_d(byte.class ); 414189251Ssam private final static MethodHandle mh_cd = mh_d(char.class ); 415189251Ssam private final static MethodHandle mh_sd = mh_d(short.class ); 416189251Ssam private final static MethodHandle mh_id = mh_d(int.class ); 417189251Ssam private final static MethodHandle mh_jd = mh_d(long.class ); 418189251Ssam private final static MethodHandle mh_fd = mh_d(float.class ); 419189251Ssam private final static MethodHandle mh_dd = mh_d(double.class ); 420189251Ssam 421189251Ssam private static void double2prim(double x) throws Throwable { 422189251Ssam assertEquals((double) x, (double) mh_dd.invokeExact(x)); // double -> double 423189251Ssam if (!DO_CASTS) return; 424189251Ssam boolean z = (((byte) x & 1) != 0); 425189251Ssam assertEquals((boolean) z, (boolean) mh_zd.invokeExact(x)); // double -> boolean 426189251Ssam assertEquals((byte) x, (byte) mh_bd.invokeExact(x)); // double -> byte 427189251Ssam assertEquals((char) x, (char) mh_cd.invokeExact(x)); // double -> char 428189251Ssam assertEquals((short) x, (short) mh_sd.invokeExact(x)); // double -> short 429189251Ssam assertEquals((int) x, (int) mh_id.invokeExact(x)); // double -> int 430189251Ssam assertEquals((long) x, (long) mh_jd.invokeExact(x)); // double -> long 431189251Ssam assertEquals((float) x, (float) mh_fd.invokeExact(x)); // double -> float 432189251Ssam } 433189251Ssam private static void double2prim_invalid(double x) throws Throwable { 434189251Ssam if (DO_CASTS) return; 435189251Ssam try { boolean y = (boolean) mh_zd.invokeExact(x); fail(); } catch (ClassCastException _) {} // double -> boolean 436189251Ssam try { byte y = (byte) mh_bd.invokeExact(x); fail(); } catch (ClassCastException _) {} // double -> byte 437189251Ssam try { char y = (char) mh_cd.invokeExact(x); fail(); } catch (ClassCastException _) {} // double -> char 438189251Ssam try { short y = (short) mh_sd.invokeExact(x); fail(); } catch (ClassCastException _) {} // double -> short 439189251Ssam try { int y = (int) mh_id.invokeExact(x); fail(); } catch (ClassCastException _) {} // double -> int 440189251Ssam try { long y = (long) mh_jd.invokeExact(x); fail(); } catch (ClassCastException _) {} // double -> long 441189251Ssam try { float y = (float) mh_fd.invokeExact(x); fail(); } catch (ClassCastException _) {} // double -> float 442189251Ssam } 443189251Ssam 444189251Ssam private final static MethodHandle mh_zv = mh(boolean.class); 445189251Ssam private final static MethodHandle mh_bv = mh(byte.class ); 446189251Ssam private final static MethodHandle mh_cv = mh(char.class ); 447189251Ssam private final static MethodHandle mh_sv = mh(short.class ); 448189251Ssam private final static MethodHandle mh_iv = mh(int.class ); 449189251Ssam private final static MethodHandle mh_jv = mh(long.class ); 450189251Ssam private final static MethodHandle mh_fv = mh(float.class ); 451189251Ssam private final static MethodHandle mh_dv = mh(double.class ); 452189251Ssam 453189251Ssam private static void void2prim(int i) throws Throwable { 454189251Ssam if (!DO_CASTS) return; 455189251Ssam assertEquals( false, (boolean) mh_zv.invokeExact()); // void -> boolean 456189251Ssam assertEquals((byte) 0, (byte) mh_bv.invokeExact()); // void -> byte 457189251Ssam assertEquals((char) 0, (char) mh_cv.invokeExact()); // void -> char 458189251Ssam assertEquals((short) 0, (short) mh_sv.invokeExact()); // void -> short 459189251Ssam assertEquals( 0, (int) mh_iv.invokeExact()); // void -> int 460189251Ssam assertEquals( 0L, (long) mh_jv.invokeExact()); // void -> long 461189251Ssam assertEquals( 0.0f, (float) mh_fv.invokeExact()); // void -> float 462189251Ssam assertEquals( 0.0d, (double) mh_dv.invokeExact()); // void -> double 463189251Ssam } 464189251Ssam 465189251Ssam private static void void2prim_invalid(double x) throws Throwable { 466189251Ssam if (DO_CASTS) return; 467189251Ssam try { assertEquals( false, (boolean) mh_zv.invokeExact()); fail(); } catch (NullPointerException _) {} // void -> boolean 468189251Ssam try { assertEquals((byte) 0, (byte) mh_bv.invokeExact()); fail(); } catch (NullPointerException _) {} // void -> byte 469189251Ssam try { assertEquals((char) 0, (char) mh_cv.invokeExact()); fail(); } catch (NullPointerException _) {} // void -> char 470189251Ssam try { assertEquals((short) 0, (short) mh_sv.invokeExact()); fail(); } catch (NullPointerException _) {} // void -> short 471189251Ssam try { assertEquals( 0, (int) mh_iv.invokeExact()); fail(); } catch (NullPointerException _) {} // void -> int 472189251Ssam try { assertEquals( 0L, (long) mh_jv.invokeExact()); fail(); } catch (NullPointerException _) {} // void -> long 473189251Ssam try { assertEquals( 0.0f, (float) mh_fv.invokeExact()); fail(); } catch (NullPointerException _) {} // void -> float 474189251Ssam try { assertEquals( 0.0d, (double) mh_dv.invokeExact()); fail(); } catch (NullPointerException _) {} // void -> double 475189251Ssam } 476189251Ssam 477189251Ssam private static MethodHandle mh_v(Class arg) { return mh(void.class, arg); } 478189251Ssam 479189251Ssam private final static MethodHandle mh_vz = mh_v(boolean.class); 480189251Ssam private final static MethodHandle mh_vb = mh_v(byte.class ); 481189251Ssam private final static MethodHandle mh_vc = mh_v(char.class ); 482189251Ssam private final static MethodHandle mh_vs = mh_v(short.class ); 483189251Ssam private final static MethodHandle mh_vi = mh_v(int.class ); 484189251Ssam private final static MethodHandle mh_vj = mh_v(long.class ); 485189251Ssam private final static MethodHandle mh_vf = mh_v(float.class ); 486189251Ssam private final static MethodHandle mh_vd = mh_v(double.class ); 487189251Ssam 488189251Ssam private static void prim2void(int x) throws Throwable { 489189251Ssam boolean z = ((x & 1) != 0); 490189251Ssam mh_vz.invokeExact( z); // boolean -> void 491189251Ssam mh_vb.invokeExact((byte) x); // byte -> void 492189251Ssam mh_vc.invokeExact((char) x); // char -> void 493189251Ssam mh_vs.invokeExact((short) x); // short -> void 494214734Srpaulo mh_vi.invokeExact((int) x); // int -> void 495189251Ssam mh_vj.invokeExact((long) x); // long -> void 496189251Ssam mh_vf.invokeExact((float) x); // float -> void 497189251Ssam mh_vd.invokeExact((double) x); // double -> void 498189251Ssam } 499189251Ssam 500189251Ssam private static void prim2void_invalid(int x) throws Throwable { 501189251Ssam // no cases 502189251Ssam } 503189251Ssam 504189251Ssam private static boolean identity(boolean v) { return v; } 505189251Ssam private static byte identity(byte v) { return v; } 506189251Ssam private static char identity(char v) { return v; } 507189251Ssam private static short identity(short v) { return v; } 508189251Ssam private static int identity(int v) { return v; } 509189251Ssam private static long identity(long v) { return v; } 510189251Ssam private static float identity(float v) { return v; } 511189251Ssam private static double identity(double v) { return v; } 512189251Ssam private static void identity() {} 513189251Ssam} 514189251Ssam