summaryrefslogtreecommitdiff
path: root/test/952-invoke-custom/src/TestVariableArityLinkerMethod.java
diff options
context:
space:
mode:
Diffstat (limited to 'test/952-invoke-custom/src/TestVariableArityLinkerMethod.java')
-rw-r--r--test/952-invoke-custom/src/TestVariableArityLinkerMethod.java569
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());
+ }
+ }
+}