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 
26 package jdk.nashorn.internal.lookup;
27 
28 import java.lang.invoke.MethodHandle;
29 import java.lang.invoke.MethodHandles;
30 import java.lang.invoke.MethodType;
31 import java.lang.invoke.SwitchPoint;
32 import java.lang.reflect.Method;
33 import 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 
40 public 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      */
filterArguments(MethodHandle target, int pos, MethodHandle... filters)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      */
filterReturnValue(MethodHandle target, MethodHandle filter)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      */
guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback)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      */
insertArguments(MethodHandle target, int pos, Object... values)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      */
dropArguments(MethodHandle target, int pos, Class<?>... valueTypes)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      */
dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes)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      */
foldArguments(MethodHandle target, MethodHandle combiner)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      */
explicitCastArguments(MethodHandle target, MethodType type)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      */
arrayElementGetter(Class<?> arrayClass)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      */
arrayElementSetter(Class<?> arrayClass)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      */
throwException(Class<?> returnType, Class<? extends Throwable> exType)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      */
catchException(final MethodHandle target, final Class<? extends Throwable> exType, final MethodHandle handler)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      */
constant(Class<?> type, Object value)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      */
identity(Class<?> type)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      */
asType(MethodHandle handle, MethodType type)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      */
asCollector(MethodHandle handle, Class<?> arrayType, int arrayLength)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      */
asSpreader(MethodHandle handle, Class<?> arrayType, int arrayLength)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      */
bindTo(MethodHandle handle, Object x)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      */
getter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type)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      */
staticGetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type)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      */
setter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type)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      */
staticSetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type)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      */
find(Method method)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      */
findStatic(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type)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      */
findVirtual(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type)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      */
findSpecial(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type, final Class<?> thisClass)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      */
createSwitchPoint()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      */
guardWithTest(SwitchPoint sp, MethodHandle before, MethodHandle after)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      */
type(Class<?> returnType, Class<?>... paramTypes)348     public MethodType type(Class<?> returnType, Class<?>... paramTypes);
349 
350 }
351 
352