diff options
Diffstat (limited to 'test/2277-methodhandle-invokeexact/src/JavaApiTest.java')
-rw-r--r-- | test/2277-methodhandle-invokeexact/src/JavaApiTest.java | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/test/2277-methodhandle-invokeexact/src/JavaApiTest.java b/test/2277-methodhandle-invokeexact/src/JavaApiTest.java new file mode 100644 index 0000000000..77b4bc0c73 --- /dev/null +++ b/test/2277-methodhandle-invokeexact/src/JavaApiTest.java @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2024 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 static java.lang.invoke.MethodType.methodType; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.Arrays; +import java.util.Optional; + +public class JavaApiTest extends AbstractInvokeExactTest { + + private static final MethodHandle OPTIONAL_GET; + + private static final MethodHandle VOID_METHOD; + private static final MethodHandle RETURN_INT; + private static final MethodHandle RETURN_DOUBLE; + private static final MethodHandle PRIVATE_INTERFACE_METHOD; + private static final MethodHandle B_PRIVATE_RETURN_INT; + private static final MethodHandle A_PRIVATE_RETURN_INT; + private static final MethodHandle STATIC_METHOD; + private static final MethodHandle EXCEPTION_THROWING_METHOD; + private static final MethodHandle INTERFACE_DEFAULT_METHOD; + private static final MethodHandle OVERWRITTEN_INTERFACE_DEFAULT_METHOD; + + private static final MethodHandle SUM_I; + private static final MethodHandle SUM_2I; + private static final MethodHandle SUM_3I; + private static final MethodHandle SUM_4I; + private static final MethodHandle SUM_5I; + private static final MethodHandle SUM_6I; + private static final MethodHandle SUM_7I; + private static final MethodHandle SUM_8I; + private static final MethodHandle SUM_9I; + private static final MethodHandle SUM_10I; + + private static final MethodHandle SUM_IJ; + private static final MethodHandle SUM_2IJ; + private static final MethodHandle SUM_3IJ; + private static final MethodHandle SUM_4IJ; + private static final MethodHandle SUM_5IJ; + + private static final MethodHandle FOO_NONDEFAULT; + private static final MethodHandle FOOBARIMPL_NONDEFAULT; + private static final MethodHandle FOO_DEFAULT; + private static final MethodHandle BAR_DEFAULT; + private static final MethodHandle FOOBAR_DEFINEDINABSTRACT; + private static final MethodHandle FOOBAR_NONDEFAULT; + private static final MethodHandle FOOBARIMPL_DEFINEDINABSTRACT; + private static final MethodHandle FOOBARIMPL_DEFAULT; + private static final MethodHandle FOO_NONOVERRIDDEN_DEFAULT; + private static final MethodHandle BAR_NONOVERRIDDEN_DEFAULT; + + static { + try { + OPTIONAL_GET = MethodHandles.lookup() + .findVirtual(Optional.class, "get", methodType(Object.class)); + + VOID_METHOD = MethodHandles.lookup() + .findVirtual(A.class, "voidMethod", methodType(void.class)); + RETURN_DOUBLE = MethodHandles.lookup() + .findVirtual(A.class, "returnDouble", methodType(double.class)); + RETURN_INT = MethodHandles.lookup() + .findVirtual(A.class, "returnInt", methodType(int.class)); + PRIVATE_INTERFACE_METHOD = MethodHandles.privateLookupIn(I.class, MethodHandles.lookup()) + .findVirtual(I.class, "innerPrivateMethod", methodType(String.class)); + A_PRIVATE_RETURN_INT = MethodHandles.privateLookupIn(A.class, MethodHandles.lookup()) + .findVirtual(A.class, "privateReturnInt", methodType(int.class)); + B_PRIVATE_RETURN_INT = MethodHandles.privateLookupIn(B.class, MethodHandles.lookup()) + .findVirtual(B.class, "privateReturnInt", methodType(int.class)); + STATIC_METHOD = MethodHandles.lookup() + .findStatic(A.class, "staticMethod", methodType(String.class, A.class)); + EXCEPTION_THROWING_METHOD = MethodHandles.lookup() + .findVirtual(A.class, "throwException", methodType(void.class)); + INTERFACE_DEFAULT_METHOD = MethodHandles.lookup() + .findVirtual(I.class, "defaultMethod", methodType(void.class)); + OVERWRITTEN_INTERFACE_DEFAULT_METHOD = MethodHandles.lookup() + .findVirtual(I.class, "overrideMe", methodType(void.class)); + + SUM_I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(1, int.class))); + SUM_2I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(2, int.class))); + SUM_3I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(3, int.class))); + SUM_4I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(4, int.class))); + SUM_5I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(5, int.class))); + SUM_6I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(6, int.class))); + SUM_7I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(7, int.class))); + SUM_8I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(8, int.class))); + SUM_9I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(9, int.class))); + SUM_10I = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(int.class, repeat(10, int.class))); + + SUM_IJ = MethodHandles.lookup() + .findVirtual(Sums.class, "sum", methodType(long.class, int.class, long.class)); + SUM_2IJ = MethodHandles.lookup() + .findVirtual(Sums.class, + "sum", + methodType(long.class, repeat(2, int.class, long.class))); + SUM_3IJ = MethodHandles.lookup() + .findVirtual(Sums.class, + "sum", + methodType(long.class, repeat(3, int.class, long.class))); + SUM_4IJ = MethodHandles.lookup() + .findVirtual(Sums.class, + "sum", + methodType(long.class, repeat(4, int.class, long.class))); + SUM_5IJ = MethodHandles.lookup() + .findVirtual(Sums.class, + "sum", + methodType(long.class, repeat(5, int.class, long.class))); + + FOO_NONDEFAULT = MethodHandles.lookup() + .findVirtual(Foo.class, "nonDefault", methodType(String.class)); + FOOBARIMPL_NONDEFAULT = MethodHandles.lookup() + .findVirtual(FooBarImpl.class, "nonDefault", methodType(String.class)); + FOO_DEFAULT = MethodHandles.lookup() + .findVirtual(Foo.class, "defaultToOverride", methodType(String.class)); + BAR_DEFAULT = MethodHandles.lookup() + .findVirtual(Bar.class, "defaultToOverride", methodType(String.class)); + FOOBAR_DEFINEDINABSTRACT = MethodHandles.lookup() + .findVirtual(FooBar.class, "definedInAbstract", methodType(String.class)); + FOOBAR_NONDEFAULT = MethodHandles.lookup() + .findVirtual(FooBar.class, "nonDefault", methodType(String.class)); + FOOBARIMPL_DEFINEDINABSTRACT = MethodHandles.lookup() + .findVirtual(FooBarImpl.class, "definedInAbstract", methodType(String.class)); + FOOBARIMPL_DEFAULT = MethodHandles.lookup() + .findVirtual(FooBarImpl.class, "defaultToOverride", methodType(String.class)); + FOO_NONOVERRIDDEN_DEFAULT = MethodHandles.lookup() + .findVirtual(Foo.class, "nonOverriddenDefault", methodType(String.class)); + BAR_NONOVERRIDDEN_DEFAULT = MethodHandles.lookup() + .findVirtual(Bar.class, "nonOverriddenDefault", methodType(String.class)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static Class<?>[] repeat(int times, Class<?> clazz) { + Class<?>[] classes = new Class<?>[times]; + Arrays.fill(classes, clazz); + return classes; + } + + private static Class<?>[] repeat(int times, Class<?> first, Class<?> second) { + Class<?>[] classes = new Class<?>[times * 2]; + for (int i = 0; i < 2 * times;) { + classes[i++] = first; + classes[i++] = second; + } + return classes; + } + + @Override + void $noinline$privateMethods() throws Throwable { + assertEquals("boo", (String) PRIVATE_INTERFACE_METHOD.invokeExact((I) new A())); + + int privateIntA = (int) A_PRIVATE_RETURN_INT.invokeExact(new A()); + assertEquals(1042, privateIntA); + + int privateIntB = (int) B_PRIVATE_RETURN_INT.invokeExact(new B()); + assertEquals(9999, privateIntB); + + privateIntB = (int) B_PRIVATE_RETURN_INT.invokeExact((B) new A()); + assertEquals(9999, privateIntB); + } + + @Override + public MethodHandle voidMethod() { + return VOID_METHOD; + } + + @Override + public MethodHandle returnDouble() { + return RETURN_DOUBLE; + } + + @Override + public MethodHandle returnInt() { + return RETURN_INT; + } + + @Override + public MethodHandle interfaceDefaultMethod() { + return INTERFACE_DEFAULT_METHOD; + } + + @Override + public MethodHandle overwrittenInterfaceDefaultMethod() { + return OVERWRITTEN_INTERFACE_DEFAULT_METHOD; + } + + @Override + public MethodHandle exceptionThrowingMethod() { + return EXCEPTION_THROWING_METHOD; + } + + @Override + public MethodHandle staticMethod() { + return STATIC_METHOD; + } + + @Override + public MethodHandle sumI() { + return SUM_I; + } + + @Override + public MethodHandle sum2I() { + return SUM_2I; + } + + @Override + public MethodHandle sum3I() { + return SUM_3I; + } + + @Override + public MethodHandle sum4I() { + return SUM_4I; + } + + @Override + public MethodHandle sum5I() { + return SUM_5I; + } + + @Override + public MethodHandle sum6I() { + return SUM_6I; + } + + @Override + public MethodHandle sum7I() { + return SUM_7I; + } + + @Override + public MethodHandle sum8I() { + return SUM_8I; + } + + @Override + public MethodHandle sum9I() { + return SUM_9I; + } + + @Override + public MethodHandle sum10I() { + return SUM_10I; + } + + @Override + public MethodHandle sumIJ() { + return SUM_IJ; + } + + @Override + public MethodHandle sum2IJ() { + return SUM_2IJ; + } + + @Override + public MethodHandle sum3IJ() { + return SUM_3IJ; + } + + @Override + public MethodHandle sum4IJ() { + return SUM_4IJ; + } + + @Override + public MethodHandle sum5IJ() { + return SUM_5IJ; + } + + @Override + public MethodHandle fooNonDefault() { + return FOO_NONDEFAULT; + } + + @Override + public MethodHandle fooBarImplNonDefault() { + return FOOBARIMPL_NONDEFAULT; + } + + @Override + public MethodHandle barDefault() { + return BAR_DEFAULT; + } + + @Override + public MethodHandle fooDefault() { + return FOO_DEFAULT; + } + + @Override + public MethodHandle fooBarImplDefault() { + return FOOBARIMPL_DEFAULT; + } + + @Override + public MethodHandle fooNonOverriddenDefault() { + return FOO_NONOVERRIDDEN_DEFAULT; + } + + @Override + public MethodHandle barNonOverriddenDefault() { + return BAR_NONOVERRIDDEN_DEFAULT; + } + + @Override + public MethodHandle fooBarDefinedInAbstract() { + return FOOBAR_DEFINEDINABSTRACT; + } + + @Override + public MethodHandle fooBarImplDefinedInAbstract() { + return FOOBARIMPL_DEFINEDINABSTRACT; + } + + @Override + public MethodHandle fooBarNonDefault() { + return FOOBAR_NONDEFAULT; + } + + @Override + public MethodHandle optionalGet() { + return OPTIONAL_GET; + } +} |