Home | History | Annotate | Download | only in src
      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
     28         protected void doTest() {
     29             try {
     30                 vh.set(3);
     31                 failUnreachable();
     32             } catch (NullPointerException ex) {
     33             }
     34         }
     35 
     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
     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 
     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
     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 
     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
    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 
    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
    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 
    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
    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 
    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
    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 
    218         public static void main(String[] args) {
    219             new UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest().run();
    220         }
    221     }
    222 
    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