1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.invoke.MethodHandles; 18 import java.lang.invoke.VarHandle; 19 import java.lang.invoke.WrongMethodTypeException; 20 21 // These tests cover DoVarHandleInvokeCommon in interpreter_common.cc. 22 23 public class VarHandleAccessorExceptionTests { 24 public static class NullReceiverTest extends VarHandleUnitTest { 25 private static final VarHandle vh = null; 26 27 @Override doTest()28 protected void doTest() { 29 try { 30 vh.set(3); 31 failUnreachable(); 32 } catch (NullPointerException ex) { 33 } 34 } 35 main(String[] args)36 public static void main(String[] args) { 37 new NullReceiverTest().run(); 38 } 39 } 40 41 public static class UnsupportedAccessModeTest extends VarHandleUnitTest { 42 private static final boolean b = true; 43 private static final VarHandle vh; 44 45 static { 46 try { 47 Class<?> cls = UnsupportedAccessModeTest.class; 48 vh = MethodHandles.lookup().findStaticVarHandle(cls, "b", boolean.class); 49 } catch (Exception e) { 50 throw new RuntimeException(e); 51 } 52 } 53 54 @Override doTest()55 protected void doTest() { 56 // A final field should not support an VarHandle access modes which can update it 57 boolean isSupported = 58 vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND); 59 assertFalse(isSupported); 60 try { 61 vh.getAndBitwiseAnd(true); 62 failUnreachable(); 63 } catch (UnsupportedOperationException ex) { 64 } 65 } 66 main(String[] args)67 public static void main(String[] args) { 68 new UnsupportedAccessModeTest().run(); 69 } 70 } 71 72 public static class WrongArgumentTypeCausingWrongMethodTypeTest extends VarHandleUnitTest { 73 private short s; 74 private static final VarHandle vh; 75 76 static { 77 try { 78 Class<?> cls = WrongArgumentTypeCausingWrongMethodTypeTest.class; 79 vh = MethodHandles.lookup().findVarHandle(cls, "s", short.class); 80 } catch (Exception e) { 81 throw new RuntimeException(e); 82 } 83 } 84 85 @Override doTest()86 protected void doTest() { 87 vh.set(this, (short) 0xcafe); 88 try { 89 vh.setVolatile(this, System.out); // System.out is a PrintStream, not short! 90 failUnreachable(); 91 } catch (WrongMethodTypeException ex) { 92 } 93 } 94 main(String[] args)95 public static void main(String[] args) { 96 new WrongArgumentTypeCausingWrongMethodTypeTest().run(); 97 } 98 } 99 100 // Too many arguments causing WMTE 101 public static class TooManyArgumentsCausingWrongMethodTypeTest extends VarHandleUnitTest { 102 private int i; 103 private static final VarHandle vh; 104 105 static { 106 try { 107 Class<?> cls = TooManyArgumentsCausingWrongMethodTypeTest.class; 108 vh = MethodHandles.lookup().findVarHandle(cls, "i", int.class); 109 } catch (Exception e) { 110 throw new RuntimeException(e); 111 } 112 } 113 114 @Override doTest()115 protected void doTest() { 116 vh.set(this, 0x12345678); 117 try { 118 vh.setVolatile(this, 0x5a5a55aa, 0xc3c30f0f); 119 failUnreachable(); 120 } catch (WrongMethodTypeException ex) { 121 } 122 } 123 main(String[] args)124 public static void main(String[] args) { 125 new TooManyArgumentsCausingWrongMethodTypeTest().run(); 126 } 127 } 128 129 public static class TooFewArgumentsCausingWrongMethodTypeTest extends VarHandleUnitTest { 130 private int i; 131 private static final VarHandle vh; 132 133 static { 134 try { 135 Class<?> cls = TooFewArgumentsCausingWrongMethodTypeTest.class; 136 vh = MethodHandles.lookup().findVarHandle(cls, "i", int.class); 137 } catch (Exception e) { 138 throw new RuntimeException(e); 139 } 140 } 141 142 @Override doTest()143 protected void doTest() { 144 i = 33; 145 vh.compareAndSet(this, 33, 44); 146 boolean updated = false; 147 try { 148 updated = (boolean) vh.compareAndSet(this, 44); 149 failUnreachable(); 150 } catch (WrongMethodTypeException ex) { 151 } 152 assertFalse(updated); // Should have failed too few arguments 153 } 154 main(String[] args)155 public static void main(String[] args) { 156 new TooFewArgumentsCausingWrongMethodTypeTest().run(); 157 } 158 } 159 160 public static class ReturnTypeCausingWrongMethodTypeTest extends VarHandleUnitTest { 161 private int i; 162 private static final VarHandle vh; 163 164 static { 165 try { 166 Class<?> cls = ReturnTypeCausingWrongMethodTypeTest.class; 167 vh = MethodHandles.lookup().findVarHandle(cls, "i", int.class); 168 } catch (Exception e) { 169 throw new RuntimeException(e); 170 } 171 } 172 173 @Override doTest()174 protected void doTest() { 175 i = 33; 176 vh.getAndSet(this, 44); 177 Runtime runtime = null; 178 try { 179 runtime = (Runtime) vh.getAndSet(this, 44); 180 failUnreachable(); 181 } catch (WrongMethodTypeException ex) { 182 } 183 assertEquals(null, runtime); 184 } 185 main(String[] args)186 public static void main(String[] args) { 187 new ReturnTypeCausingWrongMethodTypeTest().run(); 188 } 189 } 190 191 public static class UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest 192 extends VarHandleUnitTest { 193 private static final boolean b = true; 194 private static final VarHandle vh; 195 196 static { 197 try { 198 Class<?> cls = UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest.class; 199 vh = MethodHandles.lookup().findStaticVarHandle(cls, "b", boolean.class); 200 } catch (Exception e) { 201 throw new RuntimeException(e); 202 } 203 } 204 205 @Override doTest()206 protected void doTest() { 207 // A final field should not support an VarHandle access modes which can update it 208 boolean supported = vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND); 209 assertFalse(supported); 210 try { 211 // The following is both unsupported and a wrong method type... 212 vh.getAndBitwiseAnd(System.out); 213 failUnreachable(); 214 } catch (UnsupportedOperationException ex) { 215 } 216 } 217 main(String[] args)218 public static void main(String[] args) { 219 new UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest().run(); 220 } 221 } 222 main(String[] args)223 public static void main(String[] args) { 224 NullReceiverTest.main(args); 225 UnsupportedAccessModeTest.main(args); 226 WrongArgumentTypeCausingWrongMethodTypeTest.main(args); 227 TooManyArgumentsCausingWrongMethodTypeTest.main(args); 228 TooFewArgumentsCausingWrongMethodTypeTest.main(args); 229 ReturnTypeCausingWrongMethodTypeTest.main(args); 230 UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest.main(args); 231 } 232 } 233