blob: bb3ce9a760a650e11245aa8a9ef95307a792a9d5 [file] [log] [blame]
Narayan Kamath96120f42016-11-01 09:40:23 +00001/*
2 * Copyright (C) 2016 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
17import java.lang.invoke.MethodHandle;
18import java.lang.invoke.MethodHandles;
19import java.lang.invoke.MethodHandles.Lookup;
20import java.lang.invoke.MethodType;
21import java.lang.invoke.WrongMethodTypeException;
22import java.lang.invoke.Transformers.Transformer;
23
24import dalvik.system.EmulatedStackFrame;
25
26public class Main {
27
28 public static void testDelegate_allTypes(boolean z, char a, short b, int c, long d,
29 float e, double f, String g, Object h) {
30 System.out.println("boolean: " + z);
31 System.out.println("char: " + a);
32 System.out.println("short: " + b);
33 System.out.println("int: " + c);
34 System.out.println("long: " + d);
35 System.out.println("float: " + e);
36 System.out.println("double: " + f);
37 System.out.println("String: " + g);
38 System.out.println("Object: " + h);
39 }
40
41 public static boolean testDelegate_returnBoolean() {
42 return true;
43 }
44
45 public static char testDelegate_returnChar() {
46 return 'a';
47 }
48
49 public static int testDelegate_returnInt() {
50 return 42;
51 }
52
53 public static long testDelegate_returnLong() {
54 return 43;
55 }
56
57 public static float testDelegate_returnFloat() {
58 return 43.0f;
59 }
60
61 public static double testDelegate_returnDouble() {
62 return 43.0;
63 }
64
65 public static String testDelegate_returnString() {
66 return "plank";
67 }
68
69 public static class DelegatingTransformer extends Transformer {
70 private final MethodHandle delegate;
71
72 public DelegatingTransformer(MethodHandle delegate) {
73 super(delegate.type());
74 this.delegate = delegate;
75 }
76
77 @Override
78 public void transform(EmulatedStackFrame stackFrame) throws Throwable {
79 delegate.invoke(stackFrame);
80 }
81 }
82
83 public static void main(String[] args) throws Throwable {
84 MethodHandle specialFunctionHandle = MethodHandles.lookup().findStatic(
85 Main.class, "testDelegate_allTypes", MethodType.methodType(void.class,
86 new Class<?>[] { boolean.class, char.class, short.class, int.class, long.class,
87 float.class, double.class, String.class, Object.class }));
88
Igor Murashkinc0f23212017-06-21 14:07:02 -070089 MethodHandle delegate = new DelegatingTransformer(specialFunctionHandle);
Narayan Kamath96120f42016-11-01 09:40:23 +000090
91 // Test an exact invoke.
92 //
93 // Note that the shorter form below doesn't work and must be
94 // investigated on the jack side : b/32536744
95 //
96 // delegate.invokeExact(false, 'h', (short) 56, 72, Integer.MAX_VALUE + 42l,
97 // 0.56f, 100.0d, "hello", (Object) "goodbye");
98
99 Object obj = "goodbye";
100 delegate.invokeExact(false, 'h', (short) 56, 72, Integer.MAX_VALUE + 42l,
101 0.56f, 100.0d, "hello", obj);
102
103 // Test a non exact invoke with one int -> long conversion and a float -> double
104 // conversion.
105 delegate.invoke(false, 'h', (short) 56, 72, 73,
106 0.56f, 100.0f, "hello", "goodbye");
107
108 // Should throw a WrongMethodTypeException if the types don't align.
109 try {
110 delegate.invoke(false);
111 throw new AssertionError("Call to invoke unexpectedly succeeded");
112 } catch (WrongMethodTypeException expected) {
113 }
114
115 // Test return values.
116
117 // boolean.
118 MethodHandle returner = MethodHandles.lookup().findStatic(
119 Main.class, "testDelegate_returnBoolean", MethodType.methodType(boolean.class));
120 delegate = new DelegatingTransformer(returner);
121
122 System.out.println((boolean) delegate.invoke());
123 System.out.println((boolean) delegate.invokeExact());
124
125 // char.
126 returner = MethodHandles.lookup().findStatic(
127 Main.class, "testDelegate_returnChar", MethodType.methodType(char.class));
128 delegate = new DelegatingTransformer(returner);
129
130 System.out.println((char) delegate.invoke());
131 System.out.println((char) delegate.invokeExact());
132
133 // int.
134 returner = MethodHandles.lookup().findStatic(
135 Main.class, "testDelegate_returnInt", MethodType.methodType(int.class));
136 delegate = new DelegatingTransformer(returner);
137
138 System.out.println((int) delegate.invoke());
139 System.out.println((int) delegate.invokeExact());
140
141 // long.
142 returner = MethodHandles.lookup().findStatic(
143 Main.class, "testDelegate_returnLong", MethodType.methodType(long.class));
144 delegate = new DelegatingTransformer(returner);
145
146 System.out.println((long) delegate.invoke());
147 System.out.println((long) delegate.invokeExact());
148
149 // float.
150 returner = MethodHandles.lookup().findStatic(
151 Main.class, "testDelegate_returnFloat", MethodType.methodType(float.class));
152 delegate = new DelegatingTransformer(returner);
153
154 System.out.println((float) delegate.invoke());
155 System.out.println((float) delegate.invokeExact());
156
157 // double.
158 returner = MethodHandles.lookup().findStatic(
159 Main.class, "testDelegate_returnDouble", MethodType.methodType(double.class));
160 delegate = new DelegatingTransformer(returner);
161
162 System.out.println((double) delegate.invoke());
163 System.out.println((double) delegate.invokeExact());
164
165 // references.
166 returner = MethodHandles.lookup().findStatic(
167 Main.class, "testDelegate_returnString", MethodType.methodType(String.class));
168 delegate = new DelegatingTransformer(returner);
169
170 System.out.println((String) delegate.invoke());
171 System.out.println((String) delegate.invokeExact());
172 }
173}
174
175