1 /* 2 * Copyright (C) 2023 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 annotations.ConstantMethodType; 18 19 import java.lang.invoke.MethodType; 20 import java.util.Objects; 21 22 public class Main { main(String... args)23 public static void main(String... args) throws Throwable { 24 testEquality(); 25 // Subsequent const-method-type call should take value from from .bss. 26 testEquality(); 27 testNonEquality(); 28 testNonEquality(); 29 testWithUninitializableClass(); 30 } 31 unreachable()32 private static void unreachable() { 33 throw new Error("unreachable"); 34 } 35 36 @ConstantMethodType( 37 returnType = void.class, 38 parameterTypes = { 39 boolean.class, 40 byte.class, 41 char.class, 42 short.class, 43 int.class, 44 long.class, 45 float.class, 46 double.class, 47 Object.class, 48 int[].class }) takesEverythingReturnsVoid()49 private static MethodType takesEverythingReturnsVoid() { 50 unreachable(); 51 return null; 52 } 53 testEquality()54 public static void testEquality() throws Throwable { 55 MethodType actual = takesEverythingReturnsVoid(); 56 57 MethodType expected = MethodType.methodType( 58 void.class, 59 boolean.class, 60 byte.class, 61 char.class, 62 short.class, 63 int.class, 64 long.class, 65 float.class, 66 double.class, 67 Object.class, 68 int[].class); 69 70 assertSame(expected, actual); 71 assertSame(takesEverythingReturnsVoid(), takesEverythingReturnsVoid()); 72 } 73 testNonEquality()74 public static void testNonEquality() throws Throwable { 75 MethodType actual = takesEverythingReturnsVoid(); 76 77 MethodType expected = MethodType.methodType( 78 boolean.class, 79 boolean.class, 80 byte.class, 81 char.class, 82 short.class, 83 int.class, 84 long.class, 85 float.class, 86 double.class, 87 Object.class, 88 int[].class); 89 90 assertNotEqual(expected, actual); 91 } 92 93 @ConstantMethodType( 94 returnType = void.class, 95 parameterTypes = { UnloadableClass.class }) takesUnloadableReturnsVoid()96 private static MethodType takesUnloadableReturnsVoid() { 97 unreachable(); 98 return null; 99 } 100 101 public static volatile int x = 0; 102 103 private static class UnloadableClass { 104 static { 105 if (x == x) { 106 throw new RuntimeException("don't init me"); 107 } 108 } 109 } 110 testWithUninitializableClass()111 public static void testWithUninitializableClass() { 112 MethodType actual = takesUnloadableReturnsVoid(); 113 114 MethodType expected = MethodType.methodType(void.class, UnloadableClass.class); 115 116 assertSame(expected, actual); 117 } 118 assertNotEqual(Object expected, Object actual)119 public static void assertNotEqual(Object expected, Object actual) { 120 if (Objects.equals(expected, actual)) { 121 String msg = "Expected to be non equal, but got: " + expected; 122 throw new AssertionError(msg); 123 } 124 } 125 assertSame(Object expected, Object actual)126 public static void assertSame(Object expected, Object actual) { 127 if (actual != expected) { 128 String msg = String.format("Expected: %s(%X), got %s(%X)", 129 expected, 130 System.identityHashCode(expected), 131 actual, 132 System.identityHashCode(actual)); 133 throw new AssertionError(msg); 134 } 135 } 136 }