MethodHandleFunctionality.java revision 953:221a84ef44c0
1/*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.nashorn.internal.lookup;
27
28import java.lang.invoke.MethodHandle;
29import java.lang.invoke.MethodHandles;
30import java.lang.invoke.MethodType;
31import java.lang.invoke.SwitchPoint;
32import java.lang.reflect.Method;
33import java.util.List;
34
35/**
36 * Wrapper for all method handle related functions used in Nashorn. This interface only exists
37 * so that instrumentation can be added to all method handle operations.
38 */
39
40public interface MethodHandleFunctionality {
41    /**
42     * Wrapper for {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}
43     *
44     * @param target  target method handle
45     * @param pos     start argument index
46     * @param filters filters
47     *
48     * @return filtered handle
49     */
50    public MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters);
51
52    /**
53     * Wrapper for {@link MethodHandles#filterReturnValue(MethodHandle, MethodHandle)}
54     *
55     * @param target  target method handle
56     * @param filter  filter
57     *
58     * @return filtered handle
59     */
60    public MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter);
61
62    /**
63     * Wrapper for {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}
64     *
65     * @param test     test method handle
66     * @param target   target method handle when test is true
67     * @param fallback fallback method handle when test is false
68     *
69     * @return guarded handles
70     */
71    public MethodHandle guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback);
72
73    /**
74     * Wrapper for {@link MethodHandles#insertArguments(MethodHandle, int, Object...)}
75     *
76     * @param target target method handle
77     * @param pos    start argument index
78     * @param values values to insert
79     *
80     * @return handle with bound arguments
81     */
82    public MethodHandle insertArguments(MethodHandle target, int pos, Object... values);
83
84    /**
85     * Wrapper for {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}
86     *
87     * @param target     target method handle
88     * @param pos        start argument index
89     * @param valueTypes valueTypes of arguments to drop
90     *
91     * @return handle with dropped arguments
92     */
93    public MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes);
94
95    /**
96     * Wrapper for {@link MethodHandles#dropArguments(MethodHandle, int, List)}
97     *
98     * @param target     target method handle
99     * @param pos        start argument index
100     * @param valueTypes valueTypes of arguments to drop
101     *
102     * @return handle with dropped arguments
103     */
104    public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes);
105
106    /**
107     * Wrapper for {@link MethodHandles#foldArguments(MethodHandle, MethodHandle)}
108     *
109     * @param target   target method handle
110     * @param combiner combiner to apply for fold
111     *
112     * @return folded method handle
113     */
114    public MethodHandle foldArguments(MethodHandle target, MethodHandle combiner);
115
116    /**
117     * Wrapper for {@link MethodHandles#explicitCastArguments(MethodHandle, MethodType)}
118     *
119     * @param target  target method handle
120     * @param type    type to cast to
121     *
122     * @return modified method handle
123     */
124    public MethodHandle explicitCastArguments(MethodHandle target, MethodType type);
125
126    /**
127     * Wrapper for {@link java.lang.invoke.MethodHandles#arrayElementGetter(Class)}
128     *
129     * @param arrayClass class for array
130     *
131     * @return array element getter
132     */
133    public MethodHandle arrayElementGetter(Class<?> arrayClass);
134
135    /**
136     * Wrapper for {@link java.lang.invoke.MethodHandles#arrayElementSetter(Class)}
137     *
138     * @param arrayClass class for array
139     *
140     * @return array element setter
141     */
142    public MethodHandle arrayElementSetter(Class<?> arrayClass);
143
144    /**
145     * Wrapper for {@link java.lang.invoke.MethodHandles#throwException(Class, Class)}
146     *
147     * @param returnType ignored, but method signature will use it
148     * @param exType     exception type that will be thrown
149     *
150     * @return exception thrower method handle
151     */
152    public MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType);
153
154    /**
155     * Wrapper for {@link java.lang.invoke.MethodHandles#catchException(MethodHandle, Class, MethodHandle)}
156     *
157     * @param target  target method
158     * @param exType  exception type
159     * @param handler the method handle to call when exception is thrown
160     *
161     * @return exception thrower method handle
162     */
163    public MethodHandle catchException(final MethodHandle target, final Class<? extends Throwable> exType, final MethodHandle handler);
164
165    /**
166     * Wrapper for {@link java.lang.invoke.MethodHandles#constant(Class, Object)}
167     *
168     * @param type  type of constant
169     * @param value constant value
170     *
171     * @return method handle that returns said constant
172     */
173    public MethodHandle constant(Class<?> type, Object value);
174
175    /**
176     * Wrapper for {@link java.lang.invoke.MethodHandle#asType(MethodType)}
177     *
178     * @param handle  method handle for type conversion
179     * @param type    type to convert to
180     *
181     * @return method handle with given type conversion applied
182     */
183    public MethodHandle asType(MethodHandle handle, MethodType type);
184
185    /**
186     * Wrapper for {@link java.lang.invoke.MethodHandle#asCollector(Class, int)}
187     *
188     * @param handle      handle to convert
189     * @param arrayType   array type for collector array
190     * @param arrayLength length of collector array
191     *
192     * @return method handle with collector
193     */
194    public MethodHandle asCollector(MethodHandle handle, Class<?> arrayType, int arrayLength);
195
196    /**
197     * Wrapper for {@link java.lang.invoke.MethodHandle#asSpreader(Class, int)}
198     *
199     * @param handle      handle to convert
200     * @param arrayType   array type for spread
201     * @param arrayLength length of spreader
202     *
203     * @return method handle as spreader
204     */
205    public MethodHandle asSpreader(MethodHandle handle, Class<?> arrayType, int arrayLength);
206
207    /**
208     * Wrapper for {@link java.lang.invoke.MethodHandle#bindTo(Object)}
209     *
210     * @param handle a handle to which to bind a receiver
211     * @param x      the receiver
212     *
213     * @return the bound handle
214     */
215    public MethodHandle bindTo(MethodHandle handle, Object x);
216
217    /**
218     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}
219      *
220     * @param explicitLookup explicit lookup to be used
221     * @param clazz          class to look in
222     * @param name           name of field
223     * @param type           type of field
224     *
225     * @return getter method handle for virtual field
226     */
227    public MethodHandle getter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
228
229    /**
230     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter(Class, String, Class)}
231      *
232     * @param explicitLookup explicit lookup to be used
233     * @param clazz          class to look in
234     * @param name           name of field
235     * @param type           type of field
236     *
237     * @return getter method handle for static field
238     */
239    public MethodHandle staticGetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
240
241    /**
242     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findSetter(Class, String, Class)}
243      *
244     * @param explicitLookup explicit lookup to be used
245     * @param clazz          class to look in
246     * @param name           name of field
247     * @param type           type of field
248     *
249     * @return setter method handle for virtual field
250     */
251    public MethodHandle setter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
252
253    /**
254     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter(Class, String, Class)}
255      *
256     * @param explicitLookup explicit lookup to be used
257     * @param clazz          class to look in
258     * @param name           name of field
259     * @param type           type of field
260     *
261     * @return setter method handle for static field
262     */
263    public MethodHandle staticSetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
264
265    /**
266     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}
267     *
268     * Unreflect a method as a method handle
269     *
270     * @param method method to unreflect
271     * @return unreflected method as method handle
272     */
273    public MethodHandle find(Method method);
274
275    /**
276     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStatic(Class, String, MethodType)}
277     *
278     * @param explicitLookup explicit lookup to be used
279     * @param clazz          class to look in
280     * @param name           name of method
281     * @param type           method type
282     *
283     * @return method handle for static method
284     */
285    public MethodHandle findStatic(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
286
287    /**
288     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findVirtual(Class, String, MethodType)}
289     *
290     * @param explicitLookup explicit lookup to be used
291     * @param clazz          class to look in
292     * @param name           name of method
293     * @param type           method type
294     *
295     * @return method handle for virtual method
296     */
297    public MethodHandle findVirtual(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
298
299    /**
300     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findSpecial(Class, String, MethodType, Class)}
301     *
302     * @param explicitLookup explicit lookup to be used
303     * @param clazz          class to look in
304     * @param name           name of method
305     * @param type           method type
306     * @param thisClass      thisClass
307     *
308     * @return method handle for virtual method
309     */
310    public MethodHandle findSpecial(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type, final Class<?> thisClass);
311
312    /**
313     * Wrapper for SwitchPoint creation. Just like {@code new SwitchPoint()} but potentially
314     * tracked
315     *
316     * @return new switch point
317     */
318    public SwitchPoint createSwitchPoint();
319
320    /**
321     * Wrapper for {@link SwitchPoint#guardWithTest(MethodHandle, MethodHandle)}
322     *
323     * @param sp     switch point
324     * @param before method handle when switchpoint is valid
325     * @param after  method handle when switchpoint is invalidated
326     *
327     * @return guarded method handle
328     */
329    public MethodHandle guardWithTest(SwitchPoint sp, MethodHandle before, MethodHandle after);
330
331    /**
332     * Wrapper for {@link MethodType#methodType(Class, Class...)}
333     *
334     * @param returnType  return type for method type
335     * @param paramTypes  parameter types for method type
336     *
337     * @return the method type
338     */
339    public MethodType type(Class<?> returnType, Class<?>... paramTypes);
340
341}
342
343