8375712: Convert java/lang/runtime tests to use JUnit

Reviewed-by: liach
This commit is contained in:
Jan Lahoda 2026-01-26 09:42:49 +00:00
parent 0bc2dc3401
commit 90d065e677
3 changed files with 142 additions and 210 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -21,46 +21,20 @@
* questions. * questions.
*/ */
import org.testng.annotations.Test;
import java.io.Serializable;
import java.lang.Enum.EnumDesc;
import java.lang.classfile.ClassFile;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.AccessFlag;
import java.lang.runtime.ExactConversionsSupport; import java.lang.runtime.ExactConversionsSupport;
import java.lang.runtime.SwitchBootstraps; import org.junit.jupiter.api.Test;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.testng.Assert.*;
/** /**
* @test * @test
* @bug 8304487 * @bug 8304487
* @summary Verify boundary and special cases of exact conversion predicates * @summary Verify boundary and special cases of exact conversion predicates
* @compile ExactnessConversionsSupportTest.java * @compile ExactnessConversionsSupportTest.java
* @run testng/othervm ExactnessConversionsSupportTest * @run junit/othervm ExactnessConversionsSupportTest
*/ */
@Test
public class ExactnessConversionsSupportTest { public class ExactnessConversionsSupportTest {
public static void main(String[] args) { @Test
testByte(); public void testByte() {
testShort();
testChar();
testInt();
testLong();
testFloat();
testDouble();
}
public static void testByte() {
assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (Byte.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (Byte.MAX_VALUE)));
assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (0))); assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (0)));
assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (Byte.MIN_VALUE))); assertEquals(true, ExactConversionsSupport.isIntToByteExact((byte) (Byte.MIN_VALUE)));
@ -92,7 +66,8 @@ public class ExactnessConversionsSupportTest {
assertEquals(false, ExactConversionsSupport.isDoubleToByteExact(-0.0d)); assertEquals(false, ExactConversionsSupport.isDoubleToByteExact(-0.0d));
assertEquals(true, ExactConversionsSupport.isDoubleToByteExact(+0.0d)); assertEquals(true, ExactConversionsSupport.isDoubleToByteExact(+0.0d));
} }
public static void testShort() { @Test
public void testShort() {
assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (Byte.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (Byte.MAX_VALUE)));
assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (0))); assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (0)));
assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (Byte.MIN_VALUE))); assertEquals(true, ExactConversionsSupport.isIntToShortExact((byte) (Byte.MIN_VALUE)));
@ -125,7 +100,8 @@ public class ExactnessConversionsSupportTest {
assertEquals(false, ExactConversionsSupport.isDoubleToShortExact(-0.0d)); assertEquals(false, ExactConversionsSupport.isDoubleToShortExact(-0.0d));
assertEquals(true, ExactConversionsSupport.isDoubleToShortExact(+0.0d)); assertEquals(true, ExactConversionsSupport.isDoubleToShortExact(+0.0d));
} }
public static void testChar() { @Test
public void testChar() {
assertEquals(true, ExactConversionsSupport.isIntToCharExact((byte) (Byte.MAX_VALUE))); assertEquals(true, ExactConversionsSupport.isIntToCharExact((byte) (Byte.MAX_VALUE)));
assertEquals(true, ExactConversionsSupport.isIntToCharExact((byte) (0))); assertEquals(true, ExactConversionsSupport.isIntToCharExact((byte) (0)));
assertEquals(false, ExactConversionsSupport.isIntToCharExact((byte) (Byte.MIN_VALUE))); assertEquals(false, ExactConversionsSupport.isIntToCharExact((byte) (Byte.MIN_VALUE)));
@ -157,7 +133,8 @@ public class ExactnessConversionsSupportTest {
assertEquals(false, ExactConversionsSupport.isDoubleToCharExact(-0.0d)); assertEquals(false, ExactConversionsSupport.isDoubleToCharExact(-0.0d));
assertEquals(true, ExactConversionsSupport.isDoubleToCharExact(+0.0d)); assertEquals(true, ExactConversionsSupport.isDoubleToCharExact(+0.0d));
} }
public static void testInt() { @Test
public void testInt() {
assertEquals(false, ExactConversionsSupport.isLongToIntExact((Long.MAX_VALUE))); assertEquals(false, ExactConversionsSupport.isLongToIntExact((Long.MAX_VALUE)));
assertEquals(true, ExactConversionsSupport.isLongToIntExact((0L))); assertEquals(true, ExactConversionsSupport.isLongToIntExact((0L)));
assertEquals(false, ExactConversionsSupport.isLongToIntExact((Long.MIN_VALUE))); assertEquals(false, ExactConversionsSupport.isLongToIntExact((Long.MIN_VALUE)));
@ -178,7 +155,8 @@ public class ExactnessConversionsSupportTest {
assertEquals(false, ExactConversionsSupport.isDoubleToIntExact((-0.0d))); assertEquals(false, ExactConversionsSupport.isDoubleToIntExact((-0.0d)));
assertEquals(true, ExactConversionsSupport.isDoubleToIntExact((+0.0d))); assertEquals(true, ExactConversionsSupport.isDoubleToIntExact((+0.0d)));
} }
public static void testLong() { @Test
public void testLong() {
assertEquals(false, ExactConversionsSupport.isFloatToLongExact((Float.MAX_VALUE))); assertEquals(false, ExactConversionsSupport.isFloatToLongExact((Float.MAX_VALUE)));
assertEquals(true, ExactConversionsSupport.isFloatToLongExact(((float) 0))); assertEquals(true, ExactConversionsSupport.isFloatToLongExact(((float) 0)));
assertEquals(false, ExactConversionsSupport.isFloatToLongExact((Float.MIN_VALUE))); assertEquals(false, ExactConversionsSupport.isFloatToLongExact((Float.MIN_VALUE)));
@ -196,7 +174,8 @@ public class ExactnessConversionsSupportTest {
assertEquals(false, ExactConversionsSupport.isDoubleToLongExact((-0.0d))); assertEquals(false, ExactConversionsSupport.isDoubleToLongExact((-0.0d)));
assertEquals(true, ExactConversionsSupport.isDoubleToLongExact((+0.0d))); assertEquals(true, ExactConversionsSupport.isDoubleToLongExact((+0.0d)));
} }
public static void testFloat() { @Test
public void testFloat() {
assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (Byte.MAX_VALUE)))); assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (Byte.MAX_VALUE))));
assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (0)))); assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (0))));
assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (Byte.MIN_VALUE)))); assertEquals(true, ExactConversionsSupport.isIntToFloatExact(((byte) (Byte.MIN_VALUE))));
@ -220,7 +199,8 @@ public class ExactnessConversionsSupportTest {
assertEquals(true, ExactConversionsSupport.isDoubleToFloatExact((-0.0d))); assertEquals(true, ExactConversionsSupport.isDoubleToFloatExact((-0.0d)));
assertEquals(true, ExactConversionsSupport.isDoubleToFloatExact((+0.0d))); assertEquals(true, ExactConversionsSupport.isDoubleToFloatExact((+0.0d)));
} }
public static void testDouble() { @Test
public void testDouble() {
assertEquals(false, ExactConversionsSupport.isLongToDoubleExact((Long.MAX_VALUE))); assertEquals(false, ExactConversionsSupport.isLongToDoubleExact((Long.MAX_VALUE)));
assertEquals(true, ExactConversionsSupport.isLongToDoubleExact((0L))); assertEquals(true, ExactConversionsSupport.isLongToDoubleExact((0L)));
assertEquals(true, ExactConversionsSupport.isLongToDoubleExact((Long.MIN_VALUE))); assertEquals(true, ExactConversionsSupport.isLongToDoubleExact((Long.MIN_VALUE)));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,7 @@
* @test * @test
* @bug 8246774 * @bug 8246774
* @summary Basic tests for ObjectMethods * @summary Basic tests for ObjectMethods
* @run testng ObjectMethodsTest * @run junit ObjectMethodsTest
*/ */
import java.util.List; import java.util.List;
@ -34,14 +34,14 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.lang.runtime.ObjectMethods; import java.lang.runtime.ObjectMethods;
import org.testng.annotations.Test;
import static java.lang.invoke.MethodType.methodType; import static java.lang.invoke.MethodType.methodType;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@Test import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
public class ObjectMethodsTest { public class ObjectMethodsTest {
public static class C { public static class C {
@ -80,6 +80,7 @@ public class ObjectMethodsTest {
static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
@Test
public void testEqualsC() throws Throwable { public void testEqualsC() throws Throwable {
CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", C.EQUALS_DESC, C.class, C.NAME_LIST, C.ACCESSORS); CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", C.EQUALS_DESC, C.class, C.NAME_LIST, C.ACCESSORS);
MethodHandle handle = cs.dynamicInvoker(); MethodHandle handle = cs.dynamicInvoker();
@ -92,6 +93,7 @@ public class ObjectMethodsTest {
assertFalse((boolean)handle.invokeExact(c, new Object())); assertFalse((boolean)handle.invokeExact(c, new Object()));
} }
@Test
public void testEqualsEmpty() throws Throwable { public void testEqualsEmpty() throws Throwable {
CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", Empty.EQUALS_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS); CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", Empty.EQUALS_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS);
MethodHandle handle = cs.dynamicInvoker(); MethodHandle handle = cs.dynamicInvoker();
@ -102,45 +104,50 @@ public class ObjectMethodsTest {
assertFalse((boolean)handle.invokeExact(e, new Object())); assertFalse((boolean)handle.invokeExact(e, new Object()));
} }
@Test
public void testHashCodeC() throws Throwable { public void testHashCodeC() throws Throwable {
CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", C.HASHCODE_DESC, C.class, "x;y", C.ACCESSORS); CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", C.HASHCODE_DESC, C.class, "x;y", C.ACCESSORS);
MethodHandle handle = cs.dynamicInvoker(); MethodHandle handle = cs.dynamicInvoker();
C c = new C(6, 7); C c = new C(6, 7);
int hc = (int)handle.invokeExact(c); int hc = (int)handle.invokeExact(c);
assertEquals(hc, hashCombiner(c.x(), c.y())); assertEquals(hashCombiner(c.x(), c.y()), hc);
assertEquals((int)handle.invokeExact(new C(100, 1)), hashCombiner(100, 1)); assertEquals(hashCombiner(100, 1), (int)handle.invokeExact(new C(100, 1)));
assertEquals((int)handle.invokeExact(new C(0, 0)), hashCombiner(0, 0)); assertEquals(hashCombiner(0, 0), (int)handle.invokeExact(new C(0, 0)));
assertEquals((int)handle.invokeExact(new C(-1, 100)), hashCombiner(-1, 100)); assertEquals(hashCombiner(-1, 100), (int)handle.invokeExact(new C(-1, 100)));
assertEquals((int)handle.invokeExact(new C(100, 1)), hashCombiner(100, 1)); assertEquals(hashCombiner(100, 1), (int)handle.invokeExact(new C(100, 1)));
assertEquals((int)handle.invokeExact(new C(100, -1)), hashCombiner(100, -1)); assertEquals(hashCombiner(100, -1), (int)handle.invokeExact(new C(100, -1)));
} }
@Test
public void testHashCodeEmpty() throws Throwable { public void testHashCodeEmpty() throws Throwable {
CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", Empty.HASHCODE_DESC, Empty.class, "", Empty.ACCESSORS); CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", Empty.HASHCODE_DESC, Empty.class, "", Empty.ACCESSORS);
MethodHandle handle = cs.dynamicInvoker(); MethodHandle handle = cs.dynamicInvoker();
Empty e = new Empty(); Empty e = new Empty();
assertEquals((int)handle.invokeExact(e), 0); assertEquals(0, (int)handle.invokeExact(e));
} }
@Test
public void testToStringC() throws Throwable { public void testToStringC() throws Throwable {
CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, C.NAME_LIST, C.ACCESSORS); CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, C.NAME_LIST, C.ACCESSORS);
MethodHandle handle = cs.dynamicInvoker(); MethodHandle handle = cs.dynamicInvoker();
assertEquals((String)handle.invokeExact(new C(8, 9)), "C[x=8, y=9]" ); assertEquals("C[x=8, y=9]", (String)handle.invokeExact(new C(8, 9)) );
assertEquals((String)handle.invokeExact(new C(10, 11)), "C[x=10, y=11]" ); assertEquals("C[x=10, y=11]", (String)handle.invokeExact(new C(10, 11)) );
assertEquals((String)handle.invokeExact(new C(100, -9)), "C[x=100, y=-9]"); assertEquals("C[x=100, y=-9]", (String)handle.invokeExact(new C(100, -9)));
assertEquals((String)handle.invokeExact(new C(0, 0)), "C[x=0, y=0]" ); assertEquals("C[x=0, y=0]", (String)handle.invokeExact(new C(0, 0)) );
} }
@Test
public void testToStringEmpty() throws Throwable { public void testToStringEmpty() throws Throwable {
CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", Empty.TO_STRING_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS); CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", Empty.TO_STRING_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS);
MethodHandle handle = cs.dynamicInvoker(); MethodHandle handle = cs.dynamicInvoker();
assertEquals((String)handle.invokeExact(new Empty()), "Empty[]"); assertEquals("Empty[]", (String)handle.invokeExact(new Empty()));
} }
Class<NullPointerException> NPE = NullPointerException.class; Class<NullPointerException> NPE = NullPointerException.class;
Class<IllegalArgumentException> IAE = IllegalArgumentException.class; Class<IllegalArgumentException> IAE = IllegalArgumentException.class;
@Test
public void exceptions() { public void exceptions() {
assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "badName", C.EQUALS_DESC, C.class, C.NAME_LIST, C.ACCESSORS)); assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "badName", C.EQUALS_DESC, C.class, C.NAME_LIST, C.ACCESSORS));
assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, "x;y;z", C.ACCESSORS)); assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, "x;y;z", C.ACCESSORS));

View File

@ -35,21 +35,20 @@ import java.lang.runtime.SwitchBootstraps;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.classfile.ClassFile; import java.lang.classfile.ClassFile;
import org.testng.annotations.Test; import org.junit.jupiter.api.Test;
import static org.testng.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.testng.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.testng.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.testng.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
* @test * @test
* @bug 8318144 * @bug 8318144
* @enablePreview * @enablePreview
* @compile SwitchBootstrapsTest.java * @compile SwitchBootstrapsTest.java
* @run testng/othervm SwitchBootstrapsTest * @run junit/othervm SwitchBootstrapsTest
*/ */
@Test
public class SwitchBootstrapsTest { public class SwitchBootstrapsTest {
public static final MethodHandle BSM_TYPE_SWITCH; public static final MethodHandle BSM_TYPE_SWITCH;
@ -70,14 +69,14 @@ public class SwitchBootstrapsTest {
private void testType(Object target, int start, int result, Object... labels) throws Throwable { private void testType(Object target, int start, int result, Object... labels) throws Throwable {
MethodType switchType = MethodType.methodType(int.class, Object.class, int.class); MethodType switchType = MethodType.methodType(int.class, Object.class, int.class);
MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker(); MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker();
assertEquals((int) indy.invoke(target, start), result); assertEquals(result, (int) indy.invoke(target, start));
assertEquals(-1, (int) indy.invoke(null, start)); assertEquals(-1, (int) indy.invoke(null, start));
} }
private void testPrimitiveType(Object target, Class<?> targetType, int start, int result, Object... labels) throws Throwable { private void testPrimitiveType(Object target, Class<?> targetType, int start, int result, Object... labels) throws Throwable {
MethodType switchType = MethodType.methodType(int.class, targetType, int.class); MethodType switchType = MethodType.methodType(int.class, targetType, int.class);
MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker(); MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker();
assertEquals((int) indy.invoke(target, start), result); assertEquals(result, (int) indy.invoke(target, start));
} }
private void testEnum(Enum<?> target, int start, int result, Object... labels) throws Throwable { private void testEnum(Enum<?> target, int start, int result, Object... labels) throws Throwable {
@ -87,7 +86,7 @@ public class SwitchBootstrapsTest {
private void testEnum(Class<?> targetClass, Enum<?> target, int start, int result, Object... labels) throws Throwable { private void testEnum(Class<?> targetClass, Enum<?> target, int start, int result, Object... labels) throws Throwable {
MethodType switchType = MethodType.methodType(int.class, targetClass, int.class); MethodType switchType = MethodType.methodType(int.class, targetClass, int.class);
MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker(); MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels)).dynamicInvoker();
assertEquals((int) indy.invoke(target, start), result); assertEquals(result, (int) indy.invoke(target, start));
assertEquals(-1, (int) indy.invoke(null, start)); assertEquals(-1, (int) indy.invoke(null, start));
} }
@ -100,6 +99,7 @@ public class SwitchBootstrapsTest {
C; C;
} }
@Test
public void testTypes() throws Throwable { public void testTypes() throws Throwable {
testType("", 0, 0, String.class, Object.class); testType("", 0, 0, String.class, Object.class);
testType("", 0, 0, Object.class); testType("", 0, 0, Object.class);
@ -138,6 +138,7 @@ public class SwitchBootstrapsTest {
}, 0, 1, 1L); }, 0, 1, 1L);
} }
@Test
public void testPrimitiveTypes() throws Throwable { public void testPrimitiveTypes() throws Throwable {
testPrimitiveType((short) 1, short.class, 0, 1, String.class); testPrimitiveType((short) 1, short.class, 0, 1, String.class);
testPrimitiveType((byte) 1, byte.class,0, 1, String.class, byte.class); testPrimitiveType((byte) 1, byte.class,0, 1, String.class, byte.class);
@ -150,52 +151,32 @@ public class SwitchBootstrapsTest {
testPrimitiveType(true, boolean.class,0, 1, String.class, boolean.class); testPrimitiveType(true, boolean.class,0, 1, String.class, boolean.class);
} }
@Test
public void testEnums() throws Throwable { public void testEnums() throws Throwable {
testEnum(E1.A, 0, 2, "B", "C", "A", E1.class); testEnum(E1.A, 0, 2, "B", "C", "A", E1.class);
testEnum(E1.B, 0, 0, "B", "C", "A", E1.class); testEnum(E1.B, 0, 0, "B", "C", "A", E1.class);
testEnum(E1.B, 1, 3, "B", "C", "A", E1.class); testEnum(E1.B, 1, 3, "B", "C", "A", E1.class);
try { assertThrows(IllegalArgumentException.class, () ->
testEnum(E1.B, 0, -1, E2.class); testEnum(E1.B, 0, -1, E2.class)
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) { assertThrows(IllegalArgumentException.class, () ->
//OK testEnum(E1.B, 0, -1, String.class)
} );
try { assertThrows(IllegalArgumentException.class, () ->
testEnum(E1.B, 0, -1, String.class); testEnum(E1.B, 0, -1, 10)
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) { assertThrows(IllegalArgumentException.class, () ->
//OK testEnum(E1.B, 0, -1, new Object())
} );
try { assertThrows(IllegalArgumentException.class, () ->
testEnum(E1.B, 0, -1, 10); testEnum(E1.B, 0, -1, new Object[] { null })
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) { assertThrows(IllegalArgumentException.class, () ->
//OK testEnum(E1.B, 0, -1, "")
} );
try { assertThrows(NullPointerException.class, () ->
testEnum(E1.B, 0, -1, new Object()); testEnum(E1.B, 0, -1, (Object[]) null)
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) {
//OK
}
try {
testEnum(E1.B, 0, -1, new Object[] { null });
fail("Didn't get the expected exception.");
} catch (IllegalArgumentException ex) {
//OK
}
try {
testEnum(E1.B, 0, -1, "");
fail("Didn't get the expected exception.");
} catch (IllegalArgumentException ex) {
//OK
}
try {
testEnum(E1.B, 0, -1, (Object[]) null);
fail("Didn't get the expected exception.");
} catch (NullPointerException ex) {
//OK
}
testEnum(E1.B, 0, 0, "B", "A"); testEnum(E1.B, 0, 0, "B", "A");
testEnum(E1.A, 0, 1, "B", "A"); testEnum(E1.A, 0, 1, "B", "A");
testEnum(E1.A, 0, 0, "A", "A", "B"); testEnum(E1.A, 0, 0, "A", "A", "B");
@ -208,9 +189,10 @@ public class SwitchBootstrapsTest {
//null invocation name: //null invocation name:
MethodType switchType = MethodType.methodType(int.class, E1.class, int.class); MethodType switchType = MethodType.methodType(int.class, E1.class, int.class);
MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), null, switchType)).dynamicInvoker(); MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), null, switchType)).dynamicInvoker();
assertEquals((int) indy.invoke(E1.A, 0), 0); assertEquals(0, (int) indy.invoke(E1.A, 0));
} }
@Test
public void testEnumsWithConstants() throws Throwable { public void testEnumsWithConstants() throws Throwable {
enum E { enum E {
A {}, A {},
@ -239,18 +221,16 @@ public class SwitchBootstrapsTest {
testEnum(E.class, E.C, 2, 2, "A", "B"); testEnum(E.class, E.C, 2, 2, "A", "B");
} }
@Test
public void testWrongSwitchTypes() throws Throwable { public void testWrongSwitchTypes() throws Throwable {
MethodType[] switchTypes = new MethodType[] { MethodType[] switchTypes = new MethodType[] {
MethodType.methodType(int.class, Object.class), MethodType.methodType(int.class, Object.class),
MethodType.methodType(int.class, Object.class, Integer.class) MethodType.methodType(int.class, Object.class, Integer.class)
}; };
for (MethodType switchType : switchTypes) { for (MethodType switchType : switchTypes) {
try { assertThrows(IllegalArgumentException.class, () ->
BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType); BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType)
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) {
//OK, expected
}
} }
MethodType[] enumSwitchTypes = new MethodType[] { MethodType[] enumSwitchTypes = new MethodType[] {
MethodType.methodType(int.class, Enum.class), MethodType.methodType(int.class, Enum.class),
@ -259,25 +239,21 @@ public class SwitchBootstrapsTest {
MethodType.methodType(int.class, Enum.class, Integer.class) MethodType.methodType(int.class, Enum.class, Integer.class)
}; };
for (MethodType enumSwitchType : enumSwitchTypes) { for (MethodType enumSwitchType : enumSwitchTypes) {
try { assertThrows(IllegalArgumentException.class, () ->
BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType); BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType)
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) {
//OK, expected
}
} }
} }
@Test
public void testSwitchLabelTypes() throws Throwable { public void testSwitchLabelTypes() throws Throwable {
enum E {A} enum E {A}
try { assertThrows(IllegalArgumentException.class, () ->
testType(E.A, 0, -1, E.A); testType(E.A, 0, -1, E.A)
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) {
//OK, expected
}
} }
@Test
public void testSwitchQualifiedEnum() throws Throwable { public void testSwitchQualifiedEnum() throws Throwable {
enum E {A, B, C} enum E {A, B, C}
Object[] labels = new Object[] { Object[] labels = new Object[] {
@ -290,41 +266,31 @@ public class SwitchBootstrapsTest {
testType(E.C, 0, 2, labels); testType(E.C, 0, 2, labels);
} }
@Test
public void testNullLabels() throws Throwable { public void testNullLabels() throws Throwable {
MethodType switchType = MethodType.methodType(int.class, Object.class, int.class); MethodType switchType = MethodType.methodType(int.class, Object.class, int.class);
try { assertThrows(NullPointerException.class, () ->
BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, (Object[]) null); BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, (Object[]) null)
fail("Didn't get the expected exception."); );
} catch (NullPointerException ex) { assertThrows(IllegalArgumentException.class, () ->
//OK
}
try {
BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType,
new Object[] {1, null, String.class}); new Object[] {1, null, String.class})
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) {
//OK
}
MethodType enumSwitchType = MethodType.methodType(int.class, E1.class, int.class); MethodType enumSwitchType = MethodType.methodType(int.class, E1.class, int.class);
try { assertThrows(NullPointerException.class, () ->
BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, (Object[]) null); BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, (Object[]) null)
fail("Didn't get the expected exception."); );
} catch (NullPointerException ex) { assertThrows(IllegalArgumentException.class, () ->
//OK
}
try {
BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType,
new Object[] {1, null, String.class}); new Object[] {1, null, String.class})
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) {
//OK
}
//null invocationName is OK: //null invocationName is OK:
BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), null, switchType, BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), null, switchType,
new Object[] {Object.class}); new Object[] {Object.class});
} }
private static AtomicBoolean enumInitialized = new AtomicBoolean(); private static AtomicBoolean enumInitialized = new AtomicBoolean();
@Test
public void testEnumInitialization1() throws Throwable { public void testEnumInitialization1() throws Throwable {
enumInitialized.set(false); enumInitialized.set(false);
@ -340,13 +306,14 @@ public class SwitchBootstrapsTest {
CallSite invocation = (CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, new Object[] {"A"}); CallSite invocation = (CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", enumSwitchType, new Object[] {"A"});
assertFalse(enumInitialized.get()); assertFalse(enumInitialized.get());
assertEquals(invocation.dynamicInvoker().invoke(null, 0), -1); assertEquals(-1, invocation.dynamicInvoker().invoke(null, 0));
assertFalse(enumInitialized.get()); assertFalse(enumInitialized.get());
E e = E.A; E e = E.A;
assertTrue(enumInitialized.get()); assertTrue(enumInitialized.get());
assertEquals(invocation.dynamicInvoker().invoke(e, 0), 0); assertEquals(0, invocation.dynamicInvoker().invoke(e, 0));
} }
@Test
public void testEnumInitialization2() throws Throwable { public void testEnumInitialization2() throws Throwable {
enumInitialized.set(false); enumInitialized.set(false);
@ -365,60 +332,46 @@ public class SwitchBootstrapsTest {
}; };
CallSite invocation = (CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels); CallSite invocation = (CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType, labels);
assertFalse(enumInitialized.get()); assertFalse(enumInitialized.get());
assertEquals(invocation.dynamicInvoker().invoke(null, 0), -1); assertEquals(-1, invocation.dynamicInvoker().invoke(null, 0));
assertFalse(enumInitialized.get()); assertFalse(enumInitialized.get());
assertEquals(invocation.dynamicInvoker().invoke("test", 0), 1); assertEquals(1, invocation.dynamicInvoker().invoke("test", 0));
assertFalse(enumInitialized.get()); assertFalse(enumInitialized.get());
E e = E.A; E e = E.A;
assertTrue(enumInitialized.get()); assertTrue(enumInitialized.get());
assertEquals(invocation.dynamicInvoker().invoke(e, 0), 0); assertEquals(0, invocation.dynamicInvoker().invoke(e, 0));
} }
@Test
public void testIncorrectEnumLabels() throws Throwable { public void testIncorrectEnumLabels() throws Throwable {
try { assertThrows(IllegalArgumentException.class, () ->
testEnum(E1.B, 0, -1, "B", 1); testEnum(E1.B, 0, -1, "B", 1)
fail("Didn't get the expected exception."); );
} catch (IllegalArgumentException ex) { assertThrows(IllegalArgumentException.class, () ->
//OK testEnum(E1.B, 0, -1, "B", null)
} );
try {
testEnum(E1.B, 0, -1, "B", null);
fail("Didn't get the expected exception.");
} catch (IllegalArgumentException ex) {
//OK
}
} }
@Test
public void testIncorrectEnumStartIndex() throws Throwable { public void testIncorrectEnumStartIndex() throws Throwable {
try { assertThrows(IndexOutOfBoundsException.class, () ->
testEnum(E1.B, -1, -1, "B"); testEnum(E1.B, -1, -1, "B")
fail("Didn't get the expected exception."); ); //OK
} catch (IndexOutOfBoundsException ex) { assertThrows(IndexOutOfBoundsException.class, () ->
//OK testEnum(E1.B, 2, -1, "B")
} );
try {
testEnum(E1.B, 2, -1, "B");
fail("Didn't get the expected exception.");
} catch (IndexOutOfBoundsException ex) {
//OK
}
} }
@Test
public void testIncorrectTypeStartIndex() throws Throwable { public void testIncorrectTypeStartIndex() throws Throwable {
try { assertThrows(IndexOutOfBoundsException.class, () ->
testType("", -1, -1, ""); testType("", -1, -1, "")
fail("Didn't get the expected exception."); );
} catch (IndexOutOfBoundsException ex) { assertThrows(IndexOutOfBoundsException.class, () ->
//OK testType("", 2, -1, "")
} );
try {
testType("", 2, -1, "");
fail("Didn't get the expected exception.");
} catch (IndexOutOfBoundsException ex) {
//OK
}
} }
@Test
public void testHiddenClassAsCaseLabel() throws Throwable { public void testHiddenClassAsCaseLabel() throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandles.Lookup lookup = MethodHandles.lookup();
byte[] classBytes = createClass(); byte[] classBytes = createClass();
@ -448,30 +401,22 @@ public class SwitchBootstrapsTest {
}); });
} }
@Test
public void testNullLookup() throws Throwable { public void testNullLookup() throws Throwable {
try { assertThrows(NullPointerException.class, () -> {
MethodType switchType = MethodType.methodType(int.class, Object.class, int.class); MethodType switchType = MethodType.methodType(int.class, Object.class, int.class);
BSM_TYPE_SWITCH.invoke(null, "", switchType, Object.class); BSM_TYPE_SWITCH.invoke(null, "", switchType, Object.class);
fail("Didn't get the expected exception."); });
} catch (NullPointerException ex) {
//OK
}
enum E {} enum E {}
try { assertThrows(NullPointerException.class, () -> {
MethodType switchType = MethodType.methodType(int.class, E.class, int.class); MethodType switchType = MethodType.methodType(int.class, E.class, int.class);
BSM_ENUM_SWITCH.invoke(null, "", switchType, BSM_ENUM_SWITCH.invoke(null, "", switchType,
new Object[] {}); new Object[] {});
fail("Didn't get the expected exception."); });
} catch (NullPointerException ex) { assertThrows(NullPointerException.class, () -> {
//OK
}
try {
MethodType switchType = MethodType.methodType(int.class, E.class, int.class); MethodType switchType = MethodType.methodType(int.class, E.class, int.class);
BSM_ENUM_SWITCH.invoke(null, "", switchType, BSM_ENUM_SWITCH.invoke(null, "", switchType,
new Object[] {"A"}); new Object[] {"A"});
fail("Didn't get the expected exception."); });
} catch (NullPointerException ex) {
//OK
}
} }
} }