diff options
Diffstat (limited to 'test/952-invoke-custom/src/TestVariableArityLinkerMethod.java')
| -rw-r--r-- | test/952-invoke-custom/src/TestVariableArityLinkerMethod.java | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/test/952-invoke-custom/src/TestVariableArityLinkerMethod.java b/test/952-invoke-custom/src/TestVariableArityLinkerMethod.java new file mode 100644 index 00000000000..597273c8ecf --- /dev/null +++ b/test/952-invoke-custom/src/TestVariableArityLinkerMethod.java @@ -0,0 +1,569 @@ +/* + * 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 annotations.BootstrapMethod; +import annotations.CalledByIndy; +import annotations.Constant; +import java.lang.invoke.CallSite; +import java.lang.invoke.ConstantCallSite; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Arrays; + +public class TestVariableArityLinkerMethod extends TestBase { + private static void printBsmArgs(String method, Object... args) { + System.out.print(method); + System.out.print("("); + for (int i = 0; i < args.length; ++i) { + if (i != 0) { + System.out.print(", "); + } + if (args[i] != null && args[i].getClass().isArray()) { + Object array = args[i]; + if (array.getClass() == int[].class) { + System.out.print(Arrays.toString((int[]) array)); + } else if (array.getClass() == long[].class) { + System.out.print(Arrays.toString((long[]) array)); + } else if (array.getClass() == float[].class) { + System.out.print(Arrays.toString((float[]) array)); + } else if (array.getClass() == double[].class) { + System.out.print(Arrays.toString((double[]) array)); + } else { + System.out.print(Arrays.toString((Object[]) array)); + } + } else { + System.out.print(args[i]); + } + } + System.out.println(");"); + } + + private static CallSite bsmWithStringArray( + MethodHandles.Lookup lookup, + String methodName, + MethodType methodType, + String... arityArgs) + throws Throwable { + printBsmArgs("bsmWithStringArray", lookup, methodName, methodType, arityArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithStringArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + String[].class + } + ), + fieldOrMethodName = "methodA", + constantArgumentsForBootstrapMethod = { + @Constant(stringValue = "Aachen"), + @Constant(stringValue = "Aalborg"), + @Constant(stringValue = "Aalto") + } + ) + private static void methodA() { + System.out.println("methodA"); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithStringArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + String[].class + } + ), + fieldOrMethodName = "methodB", + constantArgumentsForBootstrapMethod = {@Constant(stringValue = "barium")} + ) + private static void methodB() { + System.out.println("methodB"); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithStringArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + String[].class + } + ), + fieldOrMethodName = "methodC" + ) + private static void methodC() { + System.out.println("methodC"); + } + + private static CallSite bsmWithIntAndStringArray( + MethodHandles.Lookup lookup, + String methodName, + MethodType methodType, + int extraInt, + String... extraArityArgs) + throws Throwable { + printBsmArgs( + "bsmWithIntAndStringArray", + lookup, + methodName, + methodType, + extraInt, + extraArityArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithIntAndStringArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + int.class, + String[].class + } + ), + fieldOrMethodName = "methodD", + constantArgumentsForBootstrapMethod = { + @Constant(intValue = 101), + @Constant(stringValue = "zoo"), + @Constant(stringValue = "zoogene"), + @Constant(stringValue = "zoogenic") + } + ) + private static void methodD() { + System.out.println("methodD"); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithIntAndStringArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + int.class, + String[].class + } + ), + fieldOrMethodName = "methodE", + constantArgumentsForBootstrapMethod = { + @Constant(intValue = 102), + @Constant(stringValue = "zonic") + } + ) + private static void methodE() { + System.out.println("methodE"); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithIntAndStringArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + int.class, + String[].class + } + ), + fieldOrMethodName = "methodF", + constantArgumentsForBootstrapMethod = {@Constant(intValue = 103)} + ) + private static void methodF() { + System.out.println("methodF"); + } + + private static CallSite bsmWithLongAndIntArray( + MethodHandles.Lookup lookup, + String methodName, + MethodType methodType, + long extraArg, + int... arityArgs) + throws Throwable { + printBsmArgs("bsmWithLongAndIntArray", lookup, methodName, methodType, extraArg, arityArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithLongAndIntArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + long.class, + int[].class + } + ), + fieldOrMethodName = "methodG", + constantArgumentsForBootstrapMethod = { + @Constant(longValue = 0x123456789abcdefl), + @Constant(intValue = +1), + @Constant(intValue = -1), + @Constant(intValue = +2), + @Constant(intValue = -2) + } + ) + private static void methodG() { + System.out.println("methodG"); + } + + private static CallSite bsmWithFloatAndLongArray( + MethodHandles.Lookup lookup, + String methodName, + MethodType methodType, + float extraArg, + long... arityArgs) + throws Throwable { + printBsmArgs( + "bsmWithFloatAndLongArray", lookup, methodName, methodType, extraArg, arityArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithFloatAndLongArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + float.class, + long[].class + } + ), + fieldOrMethodName = "methodH", + constantArgumentsForBootstrapMethod = { + @Constant(floatValue = (float) -Math.E), + @Constant(longValue = 999999999999l), + @Constant(longValue = -8888888888888l) + } + ) + private static void methodH() { + System.out.println("methodH"); + } + + private static CallSite bsmWithClassAndFloatArray( + MethodHandles.Lookup lookup, + String methodName, + MethodType methodType, + Class<?> extraArg, + float... arityArgs) + throws Throwable { + printBsmArgs( + "bsmWithClassAndFloatArray", lookup, methodName, methodType, extraArg, arityArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithClassAndFloatArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + Class.class, + float[].class + } + ), + fieldOrMethodName = "methodI", + constantArgumentsForBootstrapMethod = { + @Constant(classValue = Throwable.class), + @Constant(floatValue = Float.MAX_VALUE), + @Constant(floatValue = Float.MIN_VALUE), + @Constant(floatValue = (float) Math.PI), + @Constant(floatValue = (float) -Math.PI) + } + ) + private static void methodI() { + System.out.println("methodI"); + } + + private static CallSite bsmWithDoubleArray( + MethodHandles.Lookup lookup, + String methodName, + MethodType methodType, + double... arityArgs) + throws Throwable { + printBsmArgs("bsmWithDoubleArray", lookup, methodName, methodType, arityArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithDoubleArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + double[].class + } + ), + fieldOrMethodName = "methodJ", + constantArgumentsForBootstrapMethod = { + @Constant(doubleValue = Double.MAX_VALUE), + @Constant(doubleValue = Double.MIN_VALUE), + @Constant(doubleValue = Math.E), + @Constant(doubleValue = -Math.PI) + } + ) + private static void methodJ() { + System.out.println("methodJ"); + } + + private static CallSite bsmWithClassArray( + MethodHandles.Lookup lookup, + String methodName, + MethodType methodType, + Class... arityArgs) + throws Throwable { + printBsmArgs("bsmWithClassArray", lookup, methodName, methodType, arityArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithClassArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + Class[].class + } + ), + fieldOrMethodName = "methodK", + constantArgumentsForBootstrapMethod = { + @Constant(classValue = Integer.class), + @Constant(classValue = MethodHandles.class), + @Constant(classValue = Arrays.class) + } + ) + private static void methodK() { + System.out.println("methodK"); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithIntAndStringArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + int.class, + String[].class + } + ), + fieldOrMethodName = "methodO", + constantArgumentsForBootstrapMethod = {@Constant(intValue = 103), @Constant(intValue = 104)} + ) + private static void methodO() { + // Arguments are not compatible + assertNotReached(); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithIntAndStringArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + int.class, + String[].class + } + ), + fieldOrMethodName = "methodP", + constantArgumentsForBootstrapMethod = { + @Constant(intValue = 103), + @Constant(stringValue = "A"), + @Constant(stringValue = "B"), + @Constant(intValue = 42) + } + ) + private static void methodP() { + // Arguments are not compatible - specifically, the third + // component of potential collector array is an integer + // argument (42). + assertNotReached(); + } + + private static CallSite bsmWithWiderArray( + MethodHandles.Lookup lookup, String methodName, MethodType methodType, long[] extraArgs) + throws Throwable { + printBsmArgs("bsmWithWiderArray", lookup, methodName, methodType, extraArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithWiderArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + long[].class + } + ), + fieldOrMethodName = "methodQ", + constantArgumentsForBootstrapMethod = {@Constant(intValue = 103), @Constant(intValue = 42)} + ) + private static void methodQ() { + assertNotReached(); + } + + private static CallSite bsmWithBoxedArray( + MethodHandles.Lookup lookup, + String methodName, + MethodType methodType, + Integer[] extraArgs) + throws Throwable { + printBsmArgs("bsmWithBoxedArray", lookup, methodName, methodType, extraArgs); + MethodHandle mh = lookup.findStatic(lookup.lookupClass(), methodName, methodType); + return new ConstantCallSite(mh); + } + + @CalledByIndy( + bootstrapMethod = + @BootstrapMethod( + enclosingType = TestVariableArityLinkerMethod.class, + name = "bsmWithBoxedArray", + parameterTypes = { + MethodHandles.Lookup.class, + String.class, + MethodType.class, + Integer[].class + } + ), + fieldOrMethodName = "methodR", + constantArgumentsForBootstrapMethod = { + @Constant(intValue = 1030), + @Constant(intValue = 420) + } + ) + private static void methodR() { + assertNotReached(); + } + + static void test() { + // Happy cases + for (int i = 0; i < 2; ++i) { + methodA(); + methodB(); + methodC(); + } + for (int i = 0; i < 2; ++i) { + methodD(); + methodE(); + methodF(); + } + methodG(); + methodH(); + methodI(); + methodJ(); + methodK(); + + // Broken cases + try { + // bsm has incompatible static methods. Collector + // component type is String, the corresponding static + // arguments are int values. + methodO(); + assertNotReached(); + } catch (BootstrapMethodError expected) { + System.out.print("methodO => "); + System.out.print(expected.getClass()); + System.out.print(" => "); + System.out.println(expected.getCause().getClass()); + } + try { + // bsm has a trailing String array for the collector array. + // There is an int value amongst the String values. + methodP(); + assertNotReached(); + } catch (BootstrapMethodError expected) { + System.out.print("methodP => "); + System.out.print(expected.getClass()); + System.out.print(" => "); + System.out.println(expected.getCause().getClass()); + } + try { + // bsm has as trailing long[] element for the collector array. + // The corresponding static bsm arguments are of type int. + methodQ(); + assertNotReached(); + } catch (BootstrapMethodError expected) { + System.out.print("methodQ => "); + System.out.print(expected.getClass()); + System.out.print(" => "); + System.out.println(expected.getCause().getClass()); + } + try { + // bsm has as trailing Integer[] element for the collector array. + // The corresponding static bsm arguments are of type int. + methodR(); + assertNotReached(); + } catch (BootstrapMethodError expected) { + System.out.print("methodR => "); + System.out.print(expected.getClass()); + System.out.print(" => "); + System.out.println(expected.getCause().getClass()); + } + } +} |
