MethodHandleFunctionality.java revision 1036:f0b5e3900a10
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.MethodHandles#identity(Class)}
177     *
178     * @param type  type of value
179     *
180     * @return method handle that returns identity argument
181     */
182    public MethodHandle identity(Class<?> type);
183
184    /**
185     * Wrapper for {@link java.lang.invoke.MethodHandle#asType(MethodType)}
186     *
187     * @param handle  method handle for type conversion
188     * @param type    type to convert to
189     *
190     * @return method handle with given type conversion applied
191     */
192    public MethodHandle asType(MethodHandle handle, MethodType type);
193
194    /**
195     * Wrapper for {@link java.lang.invoke.MethodHandle#asCollector(Class, int)}
196     *
197     * @param handle      handle to convert
198     * @param arrayType   array type for collector array
199     * @param arrayLength length of collector array
200     *
201     * @return method handle with collector
202     */
203    public MethodHandle asCollector(MethodHandle handle, Class<?> arrayType, int arrayLength);
204
205    /**
206     * Wrapper for {@link java.lang.invoke.MethodHandle#asSpreader(Class, int)}
207     *
208     * @param handle      handle to convert
209     * @param arrayType   array type for spread
210     * @param arrayLength length of spreader
211     *
212     * @return method handle as spreader
213     */
214    public MethodHandle asSpreader(MethodHandle handle, Class<?> arrayType, int arrayLength);
215
216    /**
217     * Wrapper for {@link java.lang.invoke.MethodHandle#bindTo(Object)}
218     *
219     * @param handle a handle to which to bind a receiver
220     * @param x      the receiver
221     *
222     * @return the bound handle
223     */
224    public MethodHandle bindTo(MethodHandle handle, Object x);
225
226    /**
227     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}
228      *
229     * @param explicitLookup explicit lookup to be used
230     * @param clazz          class to look in
231     * @param name           name of field
232     * @param type           type of field
233     *
234     * @return getter method handle for virtual field
235     */
236    public MethodHandle getter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
237
238    /**
239     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter(Class, String, Class)}
240      *
241     * @param explicitLookup explicit lookup to be used
242     * @param clazz          class to look in
243     * @param name           name of field
244     * @param type           type of field
245     *
246     * @return getter method handle for static field
247     */
248    public MethodHandle staticGetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
249
250    /**
251     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findSetter(Class, String, Class)}
252      *
253     * @param explicitLookup explicit lookup to be used
254     * @param clazz          class to look in
255     * @param name           name of field
256     * @param type           type of field
257     *
258     * @return setter method handle for virtual field
259     */
260    public MethodHandle setter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
261
262    /**
263     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter(Class, String, Class)}
264      *
265     * @param explicitLookup explicit lookup to be used
266     * @param clazz          class to look in
267     * @param name           name of field
268     * @param type           type of field
269     *
270     * @return setter method handle for static field
271     */
272    public MethodHandle staticSetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
273
274    /**
275     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}
276     *
277     * Unreflect a method as a method handle
278     *
279     * @param method method to unreflect
280     * @return unreflected method as method handle
281     */
282    public MethodHandle find(Method method);
283
284    /**
285     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStatic(Class, String, MethodType)}
286     *
287     * @param explicitLookup explicit lookup to be used
288     * @param clazz          class to look in
289     * @param name           name of method
290     * @param type           method type
291     *
292     * @return method handle for static method
293     */
294    public MethodHandle findStatic(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
295
296    /**
297     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findVirtual(Class, String, MethodType)}
298     *
299     * @param explicitLookup explicit lookup to be used
300     * @param clazz          class to look in
301     * @param name           name of method
302     * @param type           method type
303     *
304     * @return method handle for virtual method
305     */
306    public MethodHandle findVirtual(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
307
308    /**
309     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findSpecial(Class, String, MethodType, Class)}
310     *
311     * @param explicitLookup explicit lookup to be used
312     * @param clazz          class to look in
313     * @param name           name of method
314     * @param type           method type
315     * @param thisClass      thisClass
316     *
317     * @return method handle for virtual method
318     */
319    public MethodHandle findSpecial(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type, final Class<?> thisClass);
320
321    /**
322     * Wrapper for SwitchPoint creation. Just like {@code new SwitchPoint()} but potentially
323     * tracked
324     *
325     * @return new switch point
326     */
327    public SwitchPoint createSwitchPoint();
328
329    /**
330     * Wrapper for {@link SwitchPoint#guardWithTest(MethodHandle, MethodHandle)}
331     *
332     * @param sp     switch point
333     * @param before method handle when switchpoint is valid
334     * @param after  method handle when switchpoint is invalidated
335     *
336     * @return guarded method handle
337     */
338    public MethodHandle guardWithTest(SwitchPoint sp, MethodHandle before, MethodHandle after);
339
340    /**
341     * Wrapper for {@link MethodType#methodType(Class, Class...)}
342     *
343     * @param returnType  return type for method type
344     * @param paramTypes  parameter types for method type
345     *
346     * @return the method type
347     */
348    public MethodType type(Class<?> returnType, Class<?>... paramTypes);
349
350}
351
352