/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.invoke.WrongMethodTypeException;
// These tests cover DoVarHandleInvokeCommon in interpreter_common.cc.
public class VarHandleAccessorExceptionTests {
public static class NullReceiverTest extends VarHandleUnitTest {
private static final VarHandle vh = null;
@Override
protected void doTest() {
try {
vh.set(3);
failUnreachable();
} catch (NullPointerException ex) {
}
}
public static void main(String[] args) {
new NullReceiverTest().run();
}
}
public static class UnsupportedAccessModeTest extends VarHandleUnitTest {
private static final boolean b = true;
private static final VarHandle vh;
static {
try {
Class<?> cls = UnsupportedAccessModeTest.class;
vh = MethodHandles.lookup().findStaticVarHandle(cls, "b", boolean.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doTest() {
// A final field should not support an VarHandle access modes which can update it
boolean isSupported =
vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND);
assertFalse(isSupported);
try {
vh.getAndBitwiseAnd(true);
failUnreachable();
} catch (UnsupportedOperationException ex) {
}
}
public static void main(String[] args) {
new UnsupportedAccessModeTest().run();
}
}
public static class WrongArgumentTypeCausingWrongMethodTypeTest extends VarHandleUnitTest {
private short s;
private static final VarHandle vh;
static {
try {
Class<?> cls = WrongArgumentTypeCausingWrongMethodTypeTest.class;
vh = MethodHandles.lookup().findVarHandle(cls, "s", short.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doTest() {
vh.set(this, (short) 0xcafe);
try {
vh.setVolatile(this, System.out); // System.out is a PrintStream, not short!
failUnreachable();
} catch (WrongMethodTypeException ex) {
}
}
public static void main(String[] args) {
new WrongArgumentTypeCausingWrongMethodTypeTest().run();
}
}
// Too many arguments causing WMTE
public static class TooManyArgumentsCausingWrongMethodTypeTest extends VarHandleUnitTest {
private int i;
private static final VarHandle vh;
static {
try {
Class<?> cls = TooManyArgumentsCausingWrongMethodTypeTest.class;
vh = MethodHandles.lookup().findVarHandle(cls, "i", int.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doTest() {
vh.set(this, 0x12345678);
try {
vh.setVolatile(this, 0x5a5a55aa, 0xc3c30f0f);
failUnreachable();
} catch (WrongMethodTypeException ex) {
}
}
public static void main(String[] args) {
new TooManyArgumentsCausingWrongMethodTypeTest().run();
}
}
public static class TooFewArgumentsCausingWrongMethodTypeTest extends VarHandleUnitTest {
private int i;
private static final VarHandle vh;
static {
try {
Class<?> cls = TooFewArgumentsCausingWrongMethodTypeTest.class;
vh = MethodHandles.lookup().findVarHandle(cls, "i", int.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doTest() {
i = 33;
vh.compareAndSet(this, 33, 44);
boolean updated = false;
try {
updated = (boolean) vh.compareAndSet(this, 44);
failUnreachable();
} catch (WrongMethodTypeException ex) {
}
assertFalse(updated); // Should have failed too few arguments
}
public static void main(String[] args) {
new TooFewArgumentsCausingWrongMethodTypeTest().run();
}
}
public static class ReturnTypeCausingWrongMethodTypeTest extends VarHandleUnitTest {
private int i;
private static final VarHandle vh;
static {
try {
Class<?> cls = ReturnTypeCausingWrongMethodTypeTest.class;
vh = MethodHandles.lookup().findVarHandle(cls, "i", int.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doTest() {
i = 33;
vh.getAndSet(this, 44);
Runtime runtime = null;
try {
runtime = (Runtime) vh.getAndSet(this, 44);
failUnreachable();
} catch (WrongMethodTypeException ex) {
}
assertEquals(null, runtime);
}
public static void main(String[] args) {
new ReturnTypeCausingWrongMethodTypeTest().run();
}
}
public static class UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest
extends VarHandleUnitTest {
private static final boolean b = true;
private static final VarHandle vh;
static {
try {
Class<?> cls = UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest.class;
vh = MethodHandles.lookup().findStaticVarHandle(cls, "b", boolean.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doTest() {
// A final field should not support an VarHandle access modes which can update it
boolean supported = vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND);
assertFalse(supported);
try {
// The following is both unsupported and a wrong method type...
vh.getAndBitwiseAnd(System.out);
failUnreachable();
} catch (UnsupportedOperationException ex) {
}
}
public static void main(String[] args) {
new UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest().run();
}
}
public static void main(String[] args) {
NullReceiverTest.main(args);
UnsupportedAccessModeTest.main(args);
WrongArgumentTypeCausingWrongMethodTypeTest.main(args);
TooManyArgumentsCausingWrongMethodTypeTest.main(args);
TooFewArgumentsCausingWrongMethodTypeTest.main(args);
ReturnTypeCausingWrongMethodTypeTest.main(args);
UnsupportedAccessModePreemptsWrongMethodTypeExceptionTest.main(args);
}
}