blob: aaf6e2f5c8f4a9491923933bb03d6bbb30d7b930 [file] [log] [blame]
Narayan Kamath000e1882016-10-24 17:14:25 +01001/*
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 testThrowException();
85
86 testDelegation();
87 }
88
89 public static void testDelegation() throws Throwable {
90 System.out.println("---");
91 System.out.println("-- testDelegation");
92 System.out.println("---");
93
94 MethodHandle specialFunctionHandle = MethodHandles.lookup().findStatic(
95 Main.class, "testDelegate_allTypes", MethodType.methodType(void.class,
96 new Class<?>[] { boolean.class, char.class, short.class, int.class, long.class,
97 float.class, double.class, String.class, Object.class }));
98
99 DelegatingTransformer delegate = new DelegatingTransformer(specialFunctionHandle);
100
101 // Test an exact invoke.
102 delegate.invokeExact(false, 'h', (short) 56, 72, Integer.MAX_VALUE + 42l,
103 0.56f, 100.0d, "hello", "goodbye");
104
105 // Test a non exact invoke with one int -> long conversion and a float -> double
106 // conversion.
107 delegate.invoke(false, 'h', (short) 56, 72, 73,
108 0.56f, 100.0f, "hello", "goodbye");
109
110 // Should throw a WrongMethodTypeException if the types don't align.
111 try {
112 delegate.invoke(false);
113 throw new AssertionError("Call to invoke unexpectedly succeeded");
114 } catch (WrongMethodTypeException expected) {
115 }
116
117 // Test return values.
118
119 // boolean.
120 MethodHandle returner = MethodHandles.lookup().findStatic(
121 Main.class, "testDelegate_returnBoolean", MethodType.methodType(boolean.class));
122 delegate = new DelegatingTransformer(returner);
123
124 System.out.println((boolean) delegate.invoke());
125 System.out.println((boolean) delegate.invokeExact());
126
127 // char.
128 returner = MethodHandles.lookup().findStatic(
129 Main.class, "testDelegate_returnChar", MethodType.methodType(char.class));
130 delegate = new DelegatingTransformer(returner);
131
132 System.out.println((char) delegate.invoke());
133 System.out.println((char) delegate.invokeExact());
134
135 // int.
136 returner = MethodHandles.lookup().findStatic(
137 Main.class, "testDelegate_returnInt", MethodType.methodType(int.class));
138 delegate = new DelegatingTransformer(returner);
139
140 System.out.println((int) delegate.invoke());
141 System.out.println((int) delegate.invokeExact());
142
143 // long.
144 returner = MethodHandles.lookup().findStatic(
145 Main.class, "testDelegate_returnLong", MethodType.methodType(long.class));
146 delegate = new DelegatingTransformer(returner);
147
148 System.out.println((long) delegate.invoke());
149 System.out.println((long) delegate.invokeExact());
150
151 // float.
152 returner = MethodHandles.lookup().findStatic(
153 Main.class, "testDelegate_returnFloat", MethodType.methodType(float.class));
154 delegate = new DelegatingTransformer(returner);
155
156 System.out.println((float) delegate.invoke());
157 System.out.println((float) delegate.invokeExact());
158
159 // double.
160 returner = MethodHandles.lookup().findStatic(
161 Main.class, "testDelegate_returnDouble", MethodType.methodType(double.class));
162 delegate = new DelegatingTransformer(returner);
163
164 System.out.println((double) delegate.invoke());
165 System.out.println((double) delegate.invokeExact());
166
167 // references.
168 returner = MethodHandles.lookup().findStatic(
169 Main.class, "testDelegate_returnString", MethodType.methodType(String.class));
170 delegate = new DelegatingTransformer(returner);
171
172 System.out.println((String) delegate.invoke());
173 System.out.println((String) delegate.invokeExact());
174 }
175
176 public static void testThrowException() throws Throwable {
177 MethodHandle handle = MethodHandles.throwException(String.class,
178 IllegalArgumentException.class);
179
180 if (handle.type().returnType() != String.class) {
181 System.out.println("Unexpected return type for handle: " + handle +
182 " [ " + handle.type() + "]");
183 }
184
185 try {
186 handle.invoke();
187 System.out.println("Expected an exception of type: java.lang.IllegalArgumentException");
188 } catch (IllegalArgumentException expected) {
189 }
190 }
191}
192
193