61 catch (Throwable t) { fail("Invokation Exception", t); } 62 63 assertTrue(newObject.getX() == newBoxed.getX()); 64 assertTrue(newObject.getY() == newBoxed.getY()); 65 assertTrue(newObject.getZ() == newBoxed.getZ()); 66 } 67 68 public static void testIncorrectBoxing() { 69 Class<?> vcc = ValueCapableClass.class; 70 Class<?> dvt = ValueType.forClass(vcc).valueClass(); 71 72 MethodHandle newDvt = newDvtMh(dvt); 73 MethodHandle box = boxMh(dvt, String.class); // Illegal box type 74 try { 75 MethodHandles.filterReturnValue(newDvt, box).invoke(); 76 fail("Expected ClassCastException"); 77 } 78 catch (ClassCastException cce) {} 79 catch (Throwable t) { fail("Invokation Exception", t); } 80 81 MethodHandle unbox = unboxMh(vcc, String.class); // Illegal unbox type 82 try { 83 unbox.invoke(ValueCapableClass.create()); 84 fail("Expected ClassCastException"); 85 } 86 catch (ClassCastException cce) {} 87 catch (Throwable t) { fail("Invokation Exception", t); } 88 } 89 90 /* 91 Create new DVT via loading a value array element. Why this workaround: 92 1) to avoid "ValueType.defaultValueConstant()" which may or may not be implemented with vunbox 93 2) vnew requires valuefactory attribute, which at the time of writing isn't generated with the DVT 94 3) vdefault doesn't exist at the time of writing 95 */ 96 public static MethodHandle newDvtMh(Class<?> dvt) { 97 return MethodHandleBuilder.loadCode(MethodHandles.lookup(), "newDvt", MethodType.methodType(dvt), CODE->{ 98 CODE.iconst_1().anewarray(dvt).iconst_0().vaload().vreturn(); 99 }); 100 } 101 102 public static MethodHandle boxMh(Class<?> inClass, Class<?> outClass) { 103 return MethodHandleBuilder.loadCode(MethodHandles.lookup(), "box", MethodType.methodType(outClass, inClass), CODE->{ 104 CODE.vload(0).vbox(outClass).areturn(); 105 }); 106 } 107 108 public static MethodHandle unboxMh(Class<?> inClass, Class<?> outClass) { 109 return MethodHandleBuilder.loadCode(MethodHandles.lookup(), "box", MethodType.methodType(outClass, inClass), CODE->{ 110 CODE.aload(0).vunbox(outClass).vreturn(); 111 }); 112 } 113 114 } | 61 catch (Throwable t) { fail("Invokation Exception", t); } 62 63 assertTrue(newObject.getX() == newBoxed.getX()); 64 assertTrue(newObject.getY() == newBoxed.getY()); 65 assertTrue(newObject.getZ() == newBoxed.getZ()); 66 } 67 68 public static void testIncorrectBoxing() { 69 Class<?> vcc = ValueCapableClass.class; 70 Class<?> dvt = ValueType.forClass(vcc).valueClass(); 71 72 MethodHandle newDvt = newDvtMh(dvt); 73 MethodHandle box = boxMh(dvt, String.class); // Illegal box type 74 try { 75 MethodHandles.filterReturnValue(newDvt, box).invoke(); 76 fail("Expected ClassCastException"); 77 } 78 catch (ClassCastException cce) {} 79 catch (Throwable t) { fail("Invokation Exception", t); } 80 81 // With -verify, this test will yield a VerifyError 82 // since the constant pool entry at the index is not a 83 // symbolic reference to a direct value class type. 84 MethodHandle unbox = unboxMh(vcc, String.class); // Illegal unbox type 85 try { 86 unbox.invoke(ValueCapableClass.create()); 87 fail("Expected ClassCastException"); 88 } 89 catch (ClassCastException cce) {} 90 catch (Throwable t) { fail("Invokation Exception", t); } 91 } 92 93 /* 94 Create new DVT via loading a value array element. Why this workaround: 95 1) to avoid "ValueType.defaultValueConstant()" which may or may not be implemented with vunbox 96 */ 97 public static MethodHandle newDvtMh(Class<?> dvt) { 98 return MethodHandleBuilder.loadCode(MethodHandles.lookup(), "newDvt", MethodType.methodType(dvt), CODE->{ 99 CODE.iconst_1().anewarray(dvt).iconst_0().vaload().vreturn(); 100 }); 101 } 102 103 public static MethodHandle boxMh(Class<?> inClass, Class<?> outClass) { 104 return MethodHandleBuilder.loadCode(MethodHandles.lookup(), "box", MethodType.methodType(outClass, inClass), CODE->{ 105 CODE.vload(0).vbox(outClass).areturn(); 106 }); 107 } 108 109 public static MethodHandle unboxMh(Class<?> inClass, Class<?> outClass) { 110 return MethodHandleBuilder.loadCode(MethodHandles.lookup(), "box", MethodType.methodType(outClass, inClass), CODE->{ 111 CODE.aload(0).vunbox(outClass).vreturn(); 112 }); 113 } 114 115 } |