author | jrose |
Fri, 18 Mar 2011 00:03:24 -0700 | |
changeset 8821 | 2836ee97ee27 |
parent 8347 | jdk/src/share/classes/sun/dyn/MethodHandleImpl.java@e5daa5772ffd |
permissions | -rw-r--r-- |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
1 |
/* |
8345
9e2483e6cfab
7013417: JSR 292 needs to support variadic method handle calls
jrose
parents:
7556
diff
changeset
|
2 |
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
4 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
10 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
15 |
* accompanied this code). |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
16 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License version |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
20 |
* |
5506 | 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. |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
24 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
25 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
26 |
package java.dyn; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
27 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
28 |
import sun.dyn.util.VerifyType; |
4537 | 29 |
import java.util.ArrayList; |
30 |
import java.util.Arrays; |
|
31 |
import java.util.Collections; |
|
32 |
import java.util.HashMap; |
|
33 |
import java.util.List; |
|
34 |
import sun.dyn.empty.Empty; |
|
35 |
import sun.dyn.util.ValueConversions; |
|
36 |
import sun.dyn.util.Wrapper; |
|
37 |
import sun.misc.Unsafe; |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
38 |
import static java.dyn.MethodHandleStatics.*; |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
39 |
import static java.dyn.MethodHandles.Lookup.IMPL_LOOKUP; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
40 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
41 |
/** |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
42 |
* Trusted implementation code for MethodHandle. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
43 |
* @author jrose |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
44 |
*/ |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
45 |
/*non-public*/ abstract class MethodHandleImpl { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
46 |
/// Factory methods to create method handles: |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
47 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
48 |
private static final MemberName.Factory LOOKUP = MemberName.Factory.INSTANCE; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
49 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
50 |
static void initStatics() { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
51 |
// Trigger preceding sequence. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
52 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
53 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
54 |
/** Look up a given method. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
55 |
* Callable only from java.dyn and related packages. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
56 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
57 |
* The resulting method handle type will be of the given type, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
58 |
* with a receiver type {@code rcvc} prepended if the member is not static. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
59 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
60 |
* Access checks are made as of the given lookup class. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
61 |
* In particular, if the method is protected and {@code defc} is in a |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
62 |
* different package from the lookup class, then {@code rcvc} must be |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
63 |
* the lookup class or a subclass. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
64 |
* @param token Proof that the lookup class has access to this package. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
65 |
* @param member Resolved method or constructor to call. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
66 |
* @param name Name of the desired method. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
67 |
* @param rcvc Receiver type of desired non-static method (else null) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
68 |
* @param doDispatch whether the method handle will test the receiver type |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
69 |
* @param lookupClass access-check relative to this class |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
70 |
* @return a direct handle to the matching method |
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
71 |
* @throws IllegalAccessException if the given method cannot be accessed by the lookup class |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
72 |
*/ |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
73 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
74 |
MethodHandle findMethod(MemberName method, |
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
75 |
boolean doDispatch, Class<?> lookupClass) throws IllegalAccessException { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
76 |
MethodType mtype = method.getMethodType(); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
77 |
if (!method.isStatic()) { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
78 |
// adjust the advertised receiver type to be exactly the one requested |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
79 |
// (in the case of invokespecial, this will be the calling class) |
2764
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
80 |
Class<?> recvType = method.getDeclaringClass(); |
4537 | 81 |
mtype = mtype.insertParameterTypes(0, recvType); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
82 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
83 |
DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
84 |
if (!mh.isValid()) |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
85 |
throw method.makeAccessException("no access", lookupClass); |
5723
a58a0eed34b0
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
5722
diff
changeset
|
86 |
assert(mh.type() == mtype); |
8345
9e2483e6cfab
7013417: JSR 292 needs to support variadic method handle calls
jrose
parents:
7556
diff
changeset
|
87 |
if (!method.isVarargs()) |
9e2483e6cfab
7013417: JSR 292 needs to support variadic method handle calls
jrose
parents:
7556
diff
changeset
|
88 |
return mh; |
9e2483e6cfab
7013417: JSR 292 needs to support variadic method handle calls
jrose
parents:
7556
diff
changeset
|
89 |
else |
9e2483e6cfab
7013417: JSR 292 needs to support variadic method handle calls
jrose
parents:
7556
diff
changeset
|
90 |
return mh.asVarargsCollector(mtype.parameterType(mtype.parameterCount()-1)); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
91 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
92 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
93 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
94 |
MethodHandle makeAllocator(MethodHandle rawConstructor) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
95 |
MethodType rawConType = rawConstructor.type(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
96 |
// Wrap the raw (unsafe) constructor with the allocation of a suitable object. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
97 |
MethodHandle allocator |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
98 |
= AllocateObject.make(rawConType.parameterType(0), rawConstructor); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
99 |
assert(allocator.type() |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
100 |
.equals(rawConType.dropParameterTypes(0, 1).changeReturnType(rawConType.parameterType(0)))); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
101 |
return allocator; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
102 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
103 |
|
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
104 |
static final class AllocateObject<C> extends BoundMethodHandle { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
105 |
private static final Unsafe unsafe = Unsafe.getUnsafe(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
106 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
107 |
private final Class<C> allocateClass; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
108 |
private final MethodHandle rawConstructor; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
109 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
110 |
private AllocateObject(MethodHandle invoker, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
111 |
Class<C> allocateClass, MethodHandle rawConstructor) { |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
112 |
super(invoker); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
113 |
this.allocateClass = allocateClass; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
114 |
this.rawConstructor = rawConstructor; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
115 |
} |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
116 |
static MethodHandle make(Class<?> allocateClass, MethodHandle rawConstructor) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
117 |
MethodType rawConType = rawConstructor.type(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
118 |
assert(rawConType.parameterType(0) == allocateClass); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
119 |
MethodType newType = rawConType.dropParameterTypes(0, 1).changeReturnType(allocateClass); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
120 |
int nargs = rawConType.parameterCount() - 1; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
121 |
if (nargs < INVOKES.length) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
122 |
MethodHandle invoke = INVOKES[nargs]; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
123 |
MethodType conType = CON_TYPES[nargs]; |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
124 |
MethodHandle gcon = convertArguments(rawConstructor, conType, rawConType, null); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
125 |
if (gcon == null) return null; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
126 |
MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
127 |
assert(galloc.type() == newType.generic()); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
128 |
return convertArguments(galloc, newType, galloc.type(), null); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
129 |
} else { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
130 |
MethodHandle invoke = VARARGS_INVOKE; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
131 |
MethodType conType = CON_TYPES[nargs]; |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
132 |
MethodHandle gcon = spreadArguments(rawConstructor, conType, 1); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
133 |
if (gcon == null) return null; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
134 |
MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
135 |
return collectArguments(galloc, newType, 1, null); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
136 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
137 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
138 |
@Override |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
139 |
public String toString() { |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
140 |
return addTypeString(allocateClass.getSimpleName(), this); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
141 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
142 |
@SuppressWarnings("unchecked") |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
143 |
private C allocate() throws InstantiationException { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
144 |
return (C) unsafe.allocateInstance(allocateClass); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
145 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
146 |
private C invoke_V(Object... av) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
147 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
148 |
rawConstructor.invokeExact((Object)obj, av); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
149 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
150 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
151 |
private C invoke_L0() throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
152 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
153 |
rawConstructor.invokeExact((Object)obj); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
154 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
155 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
156 |
private C invoke_L1(Object a0) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
157 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
158 |
rawConstructor.invokeExact((Object)obj, a0); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
159 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
160 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
161 |
private C invoke_L2(Object a0, Object a1) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
162 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
163 |
rawConstructor.invokeExact((Object)obj, a0, a1); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
164 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
165 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
166 |
private C invoke_L3(Object a0, Object a1, Object a2) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
167 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
168 |
rawConstructor.invokeExact((Object)obj, a0, a1, a2); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
169 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
170 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
171 |
private C invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
172 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
173 |
rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
174 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
175 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
176 |
private C invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
177 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
178 |
rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
179 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
180 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
181 |
private C invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
182 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
183 |
rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
184 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
185 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
186 |
private C invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
187 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
188 |
rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5, a6); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
189 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
190 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
191 |
private C invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
192 |
C obj = allocate(); |
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
193 |
rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5, a6, a7); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
194 |
return obj; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
195 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
196 |
static MethodHandle[] makeInvokes() { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
197 |
ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
198 |
MethodHandles.Lookup lookup = IMPL_LOOKUP; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
199 |
for (;;) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
200 |
int nargs = invokes.size(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
201 |
String name = "invoke_L"+nargs; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
202 |
MethodHandle invoke = null; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
203 |
try { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
204 |
invoke = lookup.findVirtual(AllocateObject.class, name, MethodType.genericMethodType(nargs)); |
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
205 |
} catch (ReflectiveOperationException ex) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
206 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
207 |
if (invoke == null) break; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
208 |
invokes.add(invoke); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
209 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
210 |
assert(invokes.size() == 9); // current number of methods |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
211 |
return invokes.toArray(new MethodHandle[0]); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
212 |
}; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
213 |
static final MethodHandle[] INVOKES = makeInvokes(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
214 |
// For testing use this: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
215 |
//static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
216 |
static final MethodHandle VARARGS_INVOKE; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
217 |
static { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
218 |
try { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
219 |
VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "invoke_V", MethodType.genericMethodType(0, true)); |
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
220 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
221 |
throw uncaughtException(ex); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
222 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
223 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
224 |
// Corresponding generic constructor types: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
225 |
static final MethodType[] CON_TYPES = new MethodType[INVOKES.length]; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
226 |
static { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
227 |
for (int i = 0; i < INVOKES.length; i++) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
228 |
CON_TYPES[i] = makeConType(INVOKES[i]); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
229 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
230 |
static final MethodType VARARGS_CON_TYPE = makeConType(VARARGS_INVOKE); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
231 |
static MethodType makeConType(MethodHandle invoke) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
232 |
MethodType invType = invoke.type(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
233 |
return invType.changeParameterType(0, Object.class).changeReturnType(void.class); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
234 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
235 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
236 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
237 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
238 |
MethodHandle accessField(MemberName member, boolean isSetter, |
4537 | 239 |
Class<?> lookupClass) { |
240 |
// Use sun. misc.Unsafe to dig up the dirt on the field. |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
241 |
MethodHandle mh = new FieldAccessor(member, isSetter); |
4537 | 242 |
return mh; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
243 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
244 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
245 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
246 |
MethodHandle accessArrayElement(Class<?> arrayClass, boolean isSetter) { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
247 |
if (!arrayClass.isArray()) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
248 |
throw newIllegalArgumentException("not an array: "+arrayClass); |
4537 | 249 |
Class<?> elemClass = arrayClass.getComponentType(); |
250 |
MethodHandle[] mhs = FieldAccessor.ARRAY_CACHE.get(elemClass); |
|
251 |
if (mhs == null) { |
|
252 |
if (!FieldAccessor.doCache(elemClass)) |
|
253 |
return FieldAccessor.ahandle(arrayClass, isSetter); |
|
254 |
mhs = new MethodHandle[] { |
|
255 |
FieldAccessor.ahandle(arrayClass, false), |
|
256 |
FieldAccessor.ahandle(arrayClass, true) |
|
257 |
}; |
|
258 |
if (mhs[0].type().parameterType(0) == Class.class) { |
|
259 |
mhs[0] = MethodHandles.insertArguments(mhs[0], 0, elemClass); |
|
260 |
mhs[1] = MethodHandles.insertArguments(mhs[1], 0, elemClass); |
|
261 |
} |
|
262 |
synchronized (FieldAccessor.ARRAY_CACHE) {} // memory barrier |
|
263 |
FieldAccessor.ARRAY_CACHE.put(elemClass, mhs); |
|
264 |
} |
|
265 |
return mhs[isSetter ? 1 : 0]; |
|
266 |
} |
|
267 |
||
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
268 |
static final class FieldAccessor<C,V> extends BoundMethodHandle { |
4537 | 269 |
private static final Unsafe unsafe = Unsafe.getUnsafe(); |
270 |
final Object base; // for static refs only |
|
271 |
final long offset; |
|
272 |
final String name; |
|
273 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
274 |
FieldAccessor(MemberName field, boolean isSetter) { |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
275 |
super(fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic())); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
276 |
this.offset = (long) field.getVMIndex(); |
4537 | 277 |
this.name = field.getName(); |
278 |
this.base = staticBase(field); |
|
279 |
} |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
280 |
@Override |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
281 |
public String toString() { return addTypeString(name, this); } |
4537 | 282 |
|
283 |
int getFieldI(C obj) { return unsafe.getInt(obj, offset); } |
|
284 |
void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); } |
|
285 |
long getFieldJ(C obj) { return unsafe.getLong(obj, offset); } |
|
286 |
void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); } |
|
287 |
float getFieldF(C obj) { return unsafe.getFloat(obj, offset); } |
|
288 |
void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); } |
|
289 |
double getFieldD(C obj) { return unsafe.getDouble(obj, offset); } |
|
290 |
void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); } |
|
291 |
boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); } |
|
292 |
void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); } |
|
293 |
byte getFieldB(C obj) { return unsafe.getByte(obj, offset); } |
|
294 |
void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); } |
|
295 |
short getFieldS(C obj) { return unsafe.getShort(obj, offset); } |
|
296 |
void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); } |
|
297 |
char getFieldC(C obj) { return unsafe.getChar(obj, offset); } |
|
298 |
void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); } |
|
299 |
@SuppressWarnings("unchecked") |
|
300 |
V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); } |
|
301 |
@SuppressWarnings("unchecked") |
|
302 |
void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); } |
|
303 |
// cast (V) is OK here, since we wrap convertArguments around the MH. |
|
304 |
||
305 |
static Object staticBase(MemberName field) { |
|
306 |
if (!field.isStatic()) return null; |
|
307 |
Class c = field.getDeclaringClass(); |
|
308 |
java.lang.reflect.Field f; |
|
309 |
try { |
|
310 |
// FIXME: Should not have to create 'f' to get this value. |
|
311 |
f = c.getDeclaredField(field.getName()); |
|
312 |
return unsafe.staticFieldBase(f); |
|
313 |
} catch (Exception ee) { |
|
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
314 |
throw uncaughtException(ee); |
4537 | 315 |
} |
316 |
} |
|
317 |
||
318 |
int getStaticI() { return unsafe.getInt(base, offset); } |
|
319 |
void setStaticI(int x) { unsafe.putInt(base, offset, x); } |
|
320 |
long getStaticJ() { return unsafe.getLong(base, offset); } |
|
321 |
void setStaticJ(long x) { unsafe.putLong(base, offset, x); } |
|
322 |
float getStaticF() { return unsafe.getFloat(base, offset); } |
|
323 |
void setStaticF(float x) { unsafe.putFloat(base, offset, x); } |
|
324 |
double getStaticD() { return unsafe.getDouble(base, offset); } |
|
325 |
void setStaticD(double x) { unsafe.putDouble(base, offset, x); } |
|
326 |
boolean getStaticZ() { return unsafe.getBoolean(base, offset); } |
|
327 |
void setStaticZ(boolean x) { unsafe.putBoolean(base, offset, x); } |
|
328 |
byte getStaticB() { return unsafe.getByte(base, offset); } |
|
329 |
void setStaticB(byte x) { unsafe.putByte(base, offset, x); } |
|
330 |
short getStaticS() { return unsafe.getShort(base, offset); } |
|
331 |
void setStaticS(short x) { unsafe.putShort(base, offset, x); } |
|
332 |
char getStaticC() { return unsafe.getChar(base, offset); } |
|
333 |
void setStaticC(char x) { unsafe.putChar(base, offset, x); } |
|
334 |
V getStaticL() { return (V) unsafe.getObject(base, offset); } |
|
335 |
void setStaticL(V x) { unsafe.putObject(base, offset, x); } |
|
336 |
||
337 |
static String fname(Class<?> vclass, boolean isSetter, boolean isStatic) { |
|
338 |
String stem; |
|
339 |
if (!isStatic) |
|
340 |
stem = (!isSetter ? "getField" : "setField"); |
|
341 |
else |
|
342 |
stem = (!isSetter ? "getStatic" : "setStatic"); |
|
343 |
return stem + Wrapper.basicTypeChar(vclass); |
|
344 |
} |
|
345 |
static MethodType ftype(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) { |
|
346 |
MethodType type; |
|
347 |
if (!isStatic) { |
|
348 |
if (!isSetter) |
|
349 |
return MethodType.methodType(vclass, cclass); |
|
350 |
else |
|
351 |
return MethodType.methodType(void.class, cclass, vclass); |
|
352 |
} else { |
|
353 |
if (!isSetter) |
|
354 |
return MethodType.methodType(vclass); |
|
355 |
else |
|
356 |
return MethodType.methodType(void.class, vclass); |
|
357 |
} |
|
358 |
} |
|
359 |
static MethodHandle fhandle(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) { |
|
360 |
String name = FieldAccessor.fname(vclass, isSetter, isStatic); |
|
361 |
if (cclass.isPrimitive()) throw newIllegalArgumentException("primitive "+cclass); |
|
362 |
Class<?> ecclass = Object.class; //erase this type |
|
363 |
Class<?> evclass = vclass; |
|
364 |
if (!evclass.isPrimitive()) evclass = Object.class; |
|
365 |
MethodType type = FieldAccessor.ftype(ecclass, evclass, isSetter, isStatic); |
|
366 |
MethodHandle mh; |
|
367 |
try { |
|
368 |
mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type); |
|
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
369 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
370 |
throw uncaughtException(ex); |
4537 | 371 |
} |
372 |
if (evclass != vclass || (!isStatic && ecclass != cclass)) { |
|
373 |
MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic); |
|
374 |
strongType = strongType.insertParameterTypes(0, FieldAccessor.class); |
|
375 |
mh = MethodHandles.convertArguments(mh, strongType); |
|
376 |
} |
|
377 |
return mh; |
|
378 |
} |
|
379 |
||
380 |
/// Support for array element access |
|
381 |
static final HashMap<Class<?>, MethodHandle[]> ARRAY_CACHE = |
|
382 |
new HashMap<Class<?>, MethodHandle[]>(); |
|
383 |
// FIXME: Cache on the classes themselves, not here. |
|
384 |
static boolean doCache(Class<?> elemClass) { |
|
385 |
if (elemClass.isPrimitive()) return true; |
|
386 |
ClassLoader cl = elemClass.getClassLoader(); |
|
387 |
return cl == null || cl == ClassLoader.getSystemClassLoader(); |
|
388 |
} |
|
389 |
static int getElementI(int[] a, int i) { return a[i]; } |
|
390 |
static void setElementI(int[] a, int i, int x) { a[i] = x; } |
|
391 |
static long getElementJ(long[] a, int i) { return a[i]; } |
|
392 |
static void setElementJ(long[] a, int i, long x) { a[i] = x; } |
|
393 |
static float getElementF(float[] a, int i) { return a[i]; } |
|
394 |
static void setElementF(float[] a, int i, float x) { a[i] = x; } |
|
395 |
static double getElementD(double[] a, int i) { return a[i]; } |
|
396 |
static void setElementD(double[] a, int i, double x) { a[i] = x; } |
|
397 |
static boolean getElementZ(boolean[] a, int i) { return a[i]; } |
|
398 |
static void setElementZ(boolean[] a, int i, boolean x) { a[i] = x; } |
|
399 |
static byte getElementB(byte[] a, int i) { return a[i]; } |
|
400 |
static void setElementB(byte[] a, int i, byte x) { a[i] = x; } |
|
401 |
static short getElementS(short[] a, int i) { return a[i]; } |
|
402 |
static void setElementS(short[] a, int i, short x) { a[i] = x; } |
|
403 |
static char getElementC(char[] a, int i) { return a[i]; } |
|
404 |
static void setElementC(char[] a, int i, char x) { a[i] = x; } |
|
405 |
static Object getElementL(Object[] a, int i) { return a[i]; } |
|
406 |
static void setElementL(Object[] a, int i, Object x) { a[i] = x; } |
|
407 |
static <V> V getElementL(Class<V[]> aclass, V[] a, int i) { return aclass.cast(a)[i]; } |
|
408 |
static <V> void setElementL(Class<V[]> aclass, V[] a, int i, V x) { aclass.cast(a)[i] = x; } |
|
409 |
||
410 |
static String aname(Class<?> aclass, boolean isSetter) { |
|
411 |
Class<?> vclass = aclass.getComponentType(); |
|
412 |
if (vclass == null) throw new IllegalArgumentException(); |
|
413 |
return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(vclass); |
|
414 |
} |
|
415 |
static MethodType atype(Class<?> aclass, boolean isSetter) { |
|
416 |
Class<?> vclass = aclass.getComponentType(); |
|
417 |
if (!isSetter) |
|
418 |
return MethodType.methodType(vclass, aclass, int.class); |
|
419 |
else |
|
420 |
return MethodType.methodType(void.class, aclass, int.class, vclass); |
|
421 |
} |
|
422 |
static MethodHandle ahandle(Class<?> aclass, boolean isSetter) { |
|
423 |
Class<?> vclass = aclass.getComponentType(); |
|
424 |
String name = FieldAccessor.aname(aclass, isSetter); |
|
425 |
Class<?> caclass = null; |
|
426 |
if (!vclass.isPrimitive() && vclass != Object.class) { |
|
427 |
caclass = aclass; |
|
428 |
aclass = Object[].class; |
|
429 |
vclass = Object.class; |
|
430 |
} |
|
431 |
MethodType type = FieldAccessor.atype(aclass, isSetter); |
|
432 |
if (caclass != null) |
|
433 |
type = type.insertParameterTypes(0, Class.class); |
|
434 |
MethodHandle mh; |
|
435 |
try { |
|
436 |
mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type); |
|
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
437 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
438 |
throw uncaughtException(ex); |
4537 | 439 |
} |
440 |
if (caclass != null) { |
|
441 |
MethodType strongType = FieldAccessor.atype(caclass, isSetter); |
|
442 |
mh = MethodHandles.insertArguments(mh, 0, caclass); |
|
443 |
mh = MethodHandles.convertArguments(mh, strongType); |
|
444 |
} |
|
445 |
return mh; |
|
446 |
} |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
447 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
448 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
449 |
/** Bind a predetermined first argument to the given direct method handle. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
450 |
* Callable only from MethodHandles. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
451 |
* @param token Proof that the caller has access to this package. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
452 |
* @param target Any direct method handle. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
453 |
* @param receiver Receiver (or first static method argument) to pre-bind. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
454 |
* @return a BoundMethodHandle for the given DirectMethodHandle, or null if it does not exist |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
455 |
*/ |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
456 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
457 |
MethodHandle bindReceiver(MethodHandle target, Object receiver) { |
7554
8a0ad9757002
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
7052
diff
changeset
|
458 |
if (target instanceof AdapterMethodHandle && |
8a0ad9757002
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
7052
diff
changeset
|
459 |
((AdapterMethodHandle)target).conversionOp() == MethodHandleNatives.Constants.OP_RETYPE_ONLY |
8a0ad9757002
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
7052
diff
changeset
|
460 |
) { |
2764
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
461 |
Object info = MethodHandleNatives.getTargetInfo(target); |
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
462 |
if (info instanceof DirectMethodHandle) { |
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
463 |
DirectMethodHandle dmh = (DirectMethodHandle) info; |
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
464 |
if (receiver == null || |
4537 | 465 |
dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) { |
466 |
MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0); |
|
467 |
MethodType newType = target.type().dropParameterTypes(0, 1); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
468 |
return convertArguments(bmh, newType, bmh.type(), null); |
4537 | 469 |
} |
2764
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
470 |
} |
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
471 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
472 |
if (target instanceof DirectMethodHandle) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
473 |
return new BoundMethodHandle((DirectMethodHandle)target, receiver, 0); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
474 |
return null; // let caller try something else |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
475 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
476 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
477 |
/** Bind a predetermined argument to the given arbitrary method handle. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
478 |
* Callable only from MethodHandles. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
479 |
* @param token Proof that the caller has access to this package. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
480 |
* @param target Any method handle. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
481 |
* @param receiver Argument (which can be a boxed primitive) to pre-bind. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
482 |
* @return a suitable BoundMethodHandle |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
483 |
*/ |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
484 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
485 |
MethodHandle bindArgument(MethodHandle target, int argnum, Object receiver) { |
4537 | 486 |
return new BoundMethodHandle(target, receiver, argnum); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
487 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
488 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
489 |
static MethodHandle convertArguments(MethodHandle target, |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
490 |
MethodType newType, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
491 |
MethodType oldType, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
492 |
int[] permutationOrNull) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
493 |
assert(oldType.parameterCount() == target.type().parameterCount()); |
4537 | 494 |
if (permutationOrNull != null) { |
495 |
int outargs = oldType.parameterCount(), inargs = newType.parameterCount(); |
|
496 |
if (permutationOrNull.length != outargs) |
|
497 |
throw newIllegalArgumentException("wrong number of arguments in permutation"); |
|
498 |
// Make the individual outgoing argument types match up first. |
|
499 |
Class<?>[] callTypeArgs = new Class<?>[outargs]; |
|
500 |
for (int i = 0; i < outargs; i++) |
|
501 |
callTypeArgs[i] = newType.parameterType(permutationOrNull[i]); |
|
502 |
MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
503 |
target = convertArguments(target, callType, oldType, null); |
4537 | 504 |
assert(target != null); |
505 |
oldType = target.type(); |
|
506 |
List<Integer> goal = new ArrayList<Integer>(); // i*TOKEN |
|
507 |
List<Integer> state = new ArrayList<Integer>(); // i*TOKEN |
|
508 |
List<Integer> drops = new ArrayList<Integer>(); // not tokens |
|
509 |
List<Integer> dups = new ArrayList<Integer>(); // not tokens |
|
510 |
final int TOKEN = 10; // to mark items which are symbolic only |
|
511 |
// state represents the argument values coming into target |
|
512 |
for (int i = 0; i < outargs; i++) { |
|
513 |
state.add(permutationOrNull[i] * TOKEN); |
|
514 |
} |
|
515 |
// goal represents the desired state |
|
516 |
for (int i = 0; i < inargs; i++) { |
|
517 |
if (state.contains(i * TOKEN)) { |
|
518 |
goal.add(i * TOKEN); |
|
519 |
} else { |
|
520 |
// adapter must initially drop all unused arguments |
|
521 |
drops.add(i); |
|
522 |
} |
|
523 |
} |
|
524 |
// detect duplications |
|
525 |
while (state.size() > goal.size()) { |
|
526 |
for (int i2 = 0; i2 < state.size(); i2++) { |
|
527 |
int arg1 = state.get(i2); |
|
528 |
int i1 = state.indexOf(arg1); |
|
529 |
if (i1 != i2) { |
|
530 |
// found duplicate occurrence at i2 |
|
531 |
int arg2 = (inargs++) * TOKEN; |
|
532 |
state.set(i2, arg2); |
|
533 |
dups.add(goal.indexOf(arg1)); |
|
534 |
goal.add(arg2); |
|
535 |
} |
|
536 |
} |
|
537 |
} |
|
538 |
assert(state.size() == goal.size()); |
|
539 |
int size = goal.size(); |
|
540 |
while (!state.equals(goal)) { |
|
541 |
// Look for a maximal sequence of adjacent misplaced arguments, |
|
542 |
// and try to rotate them into place. |
|
543 |
int bestRotArg = -10 * TOKEN, bestRotLen = 0; |
|
544 |
int thisRotArg = -10 * TOKEN, thisRotLen = 0; |
|
545 |
for (int i = 0; i < size; i++) { |
|
546 |
int arg = state.get(i); |
|
547 |
// Does this argument match the current run? |
|
548 |
if (arg == thisRotArg + TOKEN) { |
|
549 |
thisRotArg = arg; |
|
550 |
thisRotLen += 1; |
|
551 |
if (bestRotLen < thisRotLen) { |
|
552 |
bestRotLen = thisRotLen; |
|
553 |
bestRotArg = thisRotArg; |
|
554 |
} |
|
555 |
} else { |
|
556 |
// The old sequence (if any) stops here. |
|
557 |
thisRotLen = 0; |
|
558 |
thisRotArg = -10 * TOKEN; |
|
559 |
// But maybe a new one starts here also. |
|
560 |
int wantArg = goal.get(i); |
|
561 |
final int MAX_ARG_ROTATION = AdapterMethodHandle.MAX_ARG_ROTATION; |
|
562 |
if (arg != wantArg && |
|
563 |
arg >= wantArg - TOKEN * MAX_ARG_ROTATION && |
|
564 |
arg <= wantArg + TOKEN * MAX_ARG_ROTATION) { |
|
565 |
thisRotArg = arg; |
|
566 |
thisRotLen = 1; |
|
567 |
} |
|
568 |
} |
|
569 |
} |
|
570 |
if (bestRotLen >= 2) { |
|
571 |
// Do a rotation if it can improve argument positioning |
|
572 |
// by at least 2 arguments. This is not always optimal, |
|
573 |
// but it seems to catch common cases. |
|
574 |
int dstEnd = state.indexOf(bestRotArg); |
|
575 |
int srcEnd = goal.indexOf(bestRotArg); |
|
576 |
int rotBy = dstEnd - srcEnd; |
|
577 |
int dstBeg = dstEnd - (bestRotLen - 1); |
|
578 |
int srcBeg = srcEnd - (bestRotLen - 1); |
|
579 |
assert((dstEnd | dstBeg | srcEnd | srcBeg) >= 0); // no negs |
|
580 |
// Make a span which covers both source and destination. |
|
581 |
int rotBeg = Math.min(dstBeg, srcBeg); |
|
582 |
int rotEnd = Math.max(dstEnd, srcEnd); |
|
583 |
int score = 0; |
|
584 |
for (int i = rotBeg; i <= rotEnd; i++) { |
|
585 |
if ((int)state.get(i) != (int)goal.get(i)) |
|
586 |
score += 1; |
|
587 |
} |
|
588 |
List<Integer> rotSpan = state.subList(rotBeg, rotEnd+1); |
|
589 |
Collections.rotate(rotSpan, -rotBy); // reverse direction |
|
590 |
for (int i = rotBeg; i <= rotEnd; i++) { |
|
591 |
if ((int)state.get(i) != (int)goal.get(i)) |
|
592 |
score -= 1; |
|
593 |
} |
|
594 |
if (score >= 2) { |
|
595 |
// Improved at least two argument positions. Do it. |
|
596 |
List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray()); |
|
597 |
Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy); |
|
598 |
MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes); |
|
599 |
MethodHandle nextTarget |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
600 |
= AdapterMethodHandle.makeRotateArguments(rotType, target, |
4537 | 601 |
rotBeg, rotSpan.size(), rotBy); |
602 |
if (nextTarget != null) { |
|
603 |
//System.out.println("Rot: "+rotSpan+" by "+rotBy); |
|
604 |
target = nextTarget; |
|
605 |
oldType = rotType; |
|
606 |
continue; |
|
607 |
} |
|
608 |
} |
|
609 |
// Else de-rotate, and drop through to the swap-fest. |
|
610 |
Collections.rotate(rotSpan, rotBy); |
|
611 |
} |
|
612 |
||
613 |
// Now swap like the wind! |
|
614 |
List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray()); |
|
615 |
for (int i = 0; i < size; i++) { |
|
616 |
// What argument do I want here? |
|
617 |
int arg = goal.get(i); |
|
618 |
if (arg != state.get(i)) { |
|
619 |
// Where is it now? |
|
620 |
int j = state.indexOf(arg); |
|
621 |
Collections.swap(ptypes, i, j); |
|
622 |
MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
623 |
target = AdapterMethodHandle.makeSwapArguments(swapType, target, i, j); |
4537 | 624 |
if (target == null) throw newIllegalArgumentException("cannot swap"); |
625 |
assert(target.type() == swapType); |
|
626 |
oldType = swapType; |
|
627 |
Collections.swap(state, i, j); |
|
628 |
} |
|
629 |
} |
|
630 |
// One pass of swapping must finish the job. |
|
631 |
assert(state.equals(goal)); |
|
632 |
} |
|
633 |
while (!dups.isEmpty()) { |
|
634 |
// Grab a contiguous trailing sequence of dups. |
|
635 |
int grab = dups.size() - 1; |
|
636 |
int dupArgPos = dups.get(grab), dupArgCount = 1; |
|
637 |
while (grab - 1 >= 0) { |
|
638 |
int dup0 = dups.get(grab - 1); |
|
639 |
if (dup0 != dupArgPos - 1) break; |
|
640 |
dupArgPos -= 1; |
|
641 |
dupArgCount += 1; |
|
642 |
grab -= 1; |
|
643 |
} |
|
644 |
//if (dupArgCount > 1) System.out.println("Dup: "+dups.subList(grab, dups.size())); |
|
645 |
dups.subList(grab, dups.size()).clear(); |
|
646 |
// In the new target type drop that many args from the tail: |
|
647 |
List<Class<?>> ptypes = oldType.parameterList(); |
|
648 |
ptypes = ptypes.subList(0, ptypes.size() - dupArgCount); |
|
649 |
MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
650 |
target = AdapterMethodHandle.makeDupArguments(dupType, target, dupArgPos, dupArgCount); |
4537 | 651 |
if (target == null) |
652 |
throw newIllegalArgumentException("cannot dup"); |
|
653 |
oldType = target.type(); |
|
654 |
} |
|
655 |
while (!drops.isEmpty()) { |
|
656 |
// Grab a contiguous initial sequence of drops. |
|
657 |
int dropArgPos = drops.get(0), dropArgCount = 1; |
|
658 |
while (dropArgCount < drops.size()) { |
|
659 |
int drop1 = drops.get(dropArgCount); |
|
660 |
if (drop1 != dropArgPos + dropArgCount) break; |
|
661 |
dropArgCount += 1; |
|
662 |
} |
|
663 |
//if (dropArgCount > 1) System.out.println("Drop: "+drops.subList(0, dropArgCount)); |
|
664 |
drops.subList(0, dropArgCount).clear(); |
|
665 |
List<Class<?>> dropTypes = newType.parameterList() |
|
666 |
.subList(dropArgPos, dropArgPos + dropArgCount); |
|
667 |
MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
668 |
target = AdapterMethodHandle.makeDropArguments(dropType, target, dropArgPos, dropArgCount); |
4537 | 669 |
if (target == null) throw newIllegalArgumentException("cannot drop"); |
670 |
oldType = target.type(); |
|
671 |
} |
|
672 |
} |
|
673 |
if (newType == oldType) |
|
674 |
return target; |
|
675 |
if (oldType.parameterCount() != newType.parameterCount()) |
|
676 |
throw newIllegalArgumentException("mismatched parameter count"); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
677 |
MethodHandle res = AdapterMethodHandle.makePairwiseConvert(newType, target); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
678 |
if (res != null) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
679 |
return res; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
680 |
int argc = oldType.parameterCount(); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
681 |
// The JVM can't do it directly, so fill in the gap with a Java adapter. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
682 |
// TO DO: figure out what to put here from case-by-case experience |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
683 |
// Use a heavier method: Convert all the arguments to Object, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
684 |
// then back to the desired types. We might have to use Java-based |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
685 |
// method handles to do this. |
4537 | 686 |
MethodType objType = MethodType.genericMethodType(argc); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
687 |
MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(objType, target); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
688 |
if (objTarget == null) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
689 |
objTarget = FromGeneric.make(target); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
690 |
res = AdapterMethodHandle.makePairwiseConvert(newType, objTarget); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
691 |
if (res != null) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
692 |
return res; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
693 |
return ToGeneric.make(newType, objTarget); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
694 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
695 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
696 |
static MethodHandle spreadArguments(MethodHandle target, |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
697 |
MethodType newType, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
698 |
int spreadArg) { |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
699 |
// TO DO: maybe allow the restarg to be Object and implicitly cast to Object[] |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
700 |
MethodType oldType = target.type(); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
701 |
// spread the last argument of newType to oldType |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
702 |
int spreadCount = oldType.parameterCount() - spreadArg; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
703 |
Class<Object[]> spreadArgType = Object[].class; |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
704 |
MethodHandle res = AdapterMethodHandle.makeSpreadArguments(newType, target, spreadArgType, spreadArg, spreadCount); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
705 |
if (res != null) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
706 |
return res; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
707 |
// try an intermediate adapter |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
708 |
Class<?> spreadType = null; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
709 |
if (spreadArg < 0 || spreadArg >= newType.parameterCount() |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
710 |
|| !VerifyType.isSpreadArgType(spreadType = newType.parameterType(spreadArg))) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
711 |
throw newIllegalArgumentException("no restarg in "+newType); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
712 |
Class<?>[] ptypes = oldType.parameterArray(); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
713 |
for (int i = 0; i < spreadCount; i++) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
714 |
ptypes[spreadArg + i] = VerifyType.spreadArgElementType(spreadType, i); |
4537 | 715 |
MethodType midType = MethodType.methodType(newType.returnType(), ptypes); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
716 |
// after spreading, some arguments may need further conversion |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
717 |
MethodHandle target2 = convertArguments(target, midType, oldType, null); |
4537 | 718 |
if (target2 == null) |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
719 |
throw new UnsupportedOperationException("NYI: convert "+midType+" =calls=> "+oldType); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
720 |
res = AdapterMethodHandle.makeSpreadArguments(newType, target2, spreadArgType, spreadArg, spreadCount); |
4537 | 721 |
if (res != null) |
722 |
return res; |
|
723 |
res = SpreadGeneric.make(target2, spreadCount); |
|
724 |
if (res != null) |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
725 |
res = convertArguments(res, newType, res.type(), null); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
726 |
return res; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
727 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
728 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
729 |
static MethodHandle collectArguments(MethodHandle target, |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
730 |
MethodType newType, |
4537 | 731 |
int collectArg, |
732 |
MethodHandle collector) { |
|
733 |
MethodType oldType = target.type(); // (a...,c)=>r |
|
734 |
if (collector == null) { |
|
735 |
int numCollect = newType.parameterCount() - oldType.parameterCount() + 1; |
|
736 |
collector = ValueConversions.varargsArray(numCollect); |
|
737 |
} |
|
738 |
// newType // (a..., b...)=>r |
|
739 |
MethodType colType = collector.type(); // (b...)=>c |
|
740 |
// oldType // (a..., b...)=>r |
|
741 |
assert(newType.parameterCount() == collectArg + colType.parameterCount()); |
|
742 |
assert(oldType.parameterCount() == collectArg + 1); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
743 |
MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, null); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
744 |
MethodHandle gcollector = convertArguments(collector, colType.generic(), colType, null); |
4537 | 745 |
if (gtarget == null || gcollector == null) return null; |
746 |
MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
747 |
MethodHandle result = convertArguments(gresult, newType, gresult.type(), null); |
4537 | 748 |
return result; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
749 |
} |
4537 | 750 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
751 |
static MethodHandle filterArgument(MethodHandle target, |
4537 | 752 |
int pos, |
753 |
MethodHandle filter) { |
|
754 |
MethodType ttype = target.type(), gttype = ttype.generic(); |
|
755 |
if (ttype != gttype) { |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
756 |
target = convertArguments(target, gttype, ttype, null); |
4537 | 757 |
ttype = gttype; |
758 |
} |
|
759 |
MethodType ftype = filter.type(), gftype = ftype.generic(); |
|
760 |
if (ftype.parameterCount() != 1) |
|
761 |
throw new InternalError(); |
|
762 |
if (ftype != gftype) { |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
763 |
filter = convertArguments(filter, gftype, ftype, null); |
4537 | 764 |
ftype = gftype; |
765 |
} |
|
766 |
if (ftype == ttype) { |
|
767 |
// simple unary case |
|
768 |
return FilterOneArgument.make(filter, target); |
|
769 |
} |
|
770 |
return FilterGeneric.makeArgumentFilter(pos, filter, target); |
|
771 |
} |
|
772 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
773 |
static MethodHandle foldArguments(MethodHandle target, |
4537 | 774 |
MethodType newType, |
775 |
MethodHandle combiner) { |
|
776 |
MethodType oldType = target.type(); |
|
777 |
MethodType ctype = combiner.type(); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
778 |
MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, null); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
779 |
MethodHandle gcombiner = convertArguments(combiner, ctype.generic(), ctype, null); |
4537 | 780 |
if (gtarget == null || gcombiner == null) return null; |
781 |
MethodHandle gresult = FilterGeneric.makeArgumentFolder(gcombiner, gtarget); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
782 |
MethodHandle result = convertArguments(gresult, newType, gresult.type(), null); |
4537 | 783 |
return result; |
784 |
} |
|
785 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
786 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
787 |
MethodHandle dropArguments(MethodHandle target, |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
788 |
MethodType newType, int argnum) { |
4537 | 789 |
int drops = newType.parameterCount() - target.type().parameterCount(); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
790 |
MethodHandle res = AdapterMethodHandle.makeDropArguments(newType, target, argnum, drops); |
4537 | 791 |
if (res != null) |
792 |
return res; |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
793 |
throw new UnsupportedOperationException("NYI"); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
794 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
795 |
|
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
796 |
private static class GuardWithTest extends BoundMethodHandle { |
4537 | 797 |
private final MethodHandle test, target, fallback; |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
798 |
private GuardWithTest(MethodHandle invoker, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
799 |
MethodHandle test, MethodHandle target, MethodHandle fallback) { |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
800 |
super(invoker); |
4537 | 801 |
this.test = test; |
802 |
this.target = target; |
|
803 |
this.fallback = fallback; |
|
804 |
} |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
805 |
static MethodHandle make(MethodHandle test, MethodHandle target, MethodHandle fallback) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
806 |
MethodType type = target.type(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
807 |
int nargs = type.parameterCount(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
808 |
if (nargs < INVOKES.length) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
809 |
MethodHandle invoke = INVOKES[nargs]; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
810 |
MethodType gtype = type.generic(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
811 |
assert(invoke.type().dropParameterTypes(0,1) == gtype); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
812 |
MethodHandle gtest = convertArguments(test, gtype.changeReturnType(boolean.class), test.type(), null); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
813 |
MethodHandle gtarget = convertArguments(target, gtype, type, null); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
814 |
MethodHandle gfallback = convertArguments(fallback, gtype, type, null); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
815 |
if (gtest == null || gtarget == null || gfallback == null) return null; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
816 |
MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
817 |
return convertArguments(gguard, type, gtype, null); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
818 |
} else { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
819 |
MethodHandle invoke = VARARGS_INVOKE; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
820 |
MethodType gtype = MethodType.genericMethodType(1); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
821 |
assert(invoke.type().dropParameterTypes(0,1) == gtype); |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
822 |
MethodHandle gtest = spreadArguments(test, gtype.changeReturnType(boolean.class), 0); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
823 |
MethodHandle gtarget = spreadArguments(target, gtype, 0); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
824 |
MethodHandle gfallback = spreadArguments(fallback, gtype, 0); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
825 |
MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
826 |
if (gtest == null || gtarget == null || gfallback == null) return null; |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
827 |
return collectArguments(gguard, type, 0, null); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
828 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
829 |
} |
4537 | 830 |
@Override |
831 |
public String toString() { |
|
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
832 |
return addTypeString(target, this); |
4537 | 833 |
} |
834 |
private Object invoke_V(Object... av) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
835 |
if ((boolean) test.invokeExact(av)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
836 |
return target.invokeExact(av); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
837 |
return fallback.invokeExact(av); |
4537 | 838 |
} |
839 |
private Object invoke_L0() throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
840 |
if ((boolean) test.invokeExact()) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
841 |
return target.invokeExact(); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
842 |
return fallback.invokeExact(); |
4537 | 843 |
} |
844 |
private Object invoke_L1(Object a0) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
845 |
if ((boolean) test.invokeExact(a0)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
846 |
return target.invokeExact(a0); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
847 |
return fallback.invokeExact(a0); |
4537 | 848 |
} |
849 |
private Object invoke_L2(Object a0, Object a1) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
850 |
if ((boolean) test.invokeExact(a0, a1)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
851 |
return target.invokeExact(a0, a1); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
852 |
return fallback.invokeExact(a0, a1); |
4537 | 853 |
} |
854 |
private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
855 |
if ((boolean) test.invokeExact(a0, a1, a2)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
856 |
return target.invokeExact(a0, a1, a2); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
857 |
return fallback.invokeExact(a0, a1, a2); |
4537 | 858 |
} |
859 |
private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
860 |
if ((boolean) test.invokeExact(a0, a1, a2, a3)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
861 |
return target.invokeExact(a0, a1, a2, a3); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
862 |
return fallback.invokeExact(a0, a1, a2, a3); |
4537 | 863 |
} |
864 |
private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
865 |
if ((boolean) test.invokeExact(a0, a1, a2, a3, a4)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
866 |
return target.invokeExact(a0, a1, a2, a3, a4); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
867 |
return fallback.invokeExact(a0, a1, a2, a3, a4); |
4537 | 868 |
} |
869 |
private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
870 |
if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
871 |
return target.invokeExact(a0, a1, a2, a3, a4, a5); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
872 |
return fallback.invokeExact(a0, a1, a2, a3, a4, a5); |
4537 | 873 |
} |
874 |
private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
875 |
if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5, a6)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
876 |
return target.invokeExact(a0, a1, a2, a3, a4, a5, a6); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
877 |
return fallback.invokeExact(a0, a1, a2, a3, a4, a5, a6); |
4537 | 878 |
} |
879 |
private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
880 |
if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7)) |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
881 |
return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7); |
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
882 |
return fallback.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7); |
4537 | 883 |
} |
884 |
static MethodHandle[] makeInvokes() { |
|
885 |
ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>(); |
|
886 |
MethodHandles.Lookup lookup = IMPL_LOOKUP; |
|
887 |
for (;;) { |
|
888 |
int nargs = invokes.size(); |
|
889 |
String name = "invoke_L"+nargs; |
|
890 |
MethodHandle invoke = null; |
|
891 |
try { |
|
892 |
invoke = lookup.findVirtual(GuardWithTest.class, name, MethodType.genericMethodType(nargs)); |
|
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
893 |
} catch (ReflectiveOperationException ex) { |
4537 | 894 |
} |
895 |
if (invoke == null) break; |
|
896 |
invokes.add(invoke); |
|
897 |
} |
|
898 |
assert(invokes.size() == 9); // current number of methods |
|
899 |
return invokes.toArray(new MethodHandle[0]); |
|
900 |
}; |
|
901 |
static final MethodHandle[] INVOKES = makeInvokes(); |
|
902 |
// For testing use this: |
|
903 |
//static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2); |
|
904 |
static final MethodHandle VARARGS_INVOKE; |
|
905 |
static { |
|
906 |
try { |
|
907 |
VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithTest.class, "invoke_V", MethodType.genericMethodType(0, true)); |
|
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
908 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
909 |
throw uncaughtException(ex); |
4537 | 910 |
} |
911 |
} |
|
912 |
} |
|
913 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
914 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
915 |
MethodHandle makeGuardWithTest(MethodHandle test, |
4537 | 916 |
MethodHandle target, |
917 |
MethodHandle fallback) { |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
918 |
return GuardWithTest.make(test, target, fallback); |
4537 | 919 |
} |
920 |
||
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
921 |
private static class GuardWithCatch extends BoundMethodHandle { |
4537 | 922 |
private final MethodHandle target; |
923 |
private final Class<? extends Throwable> exType; |
|
924 |
private final MethodHandle catcher; |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
925 |
GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { |
4537 | 926 |
this(INVOKES[target.type().parameterCount()], target, exType, catcher); |
927 |
} |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
928 |
GuardWithCatch(MethodHandle invoker, |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
929 |
MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
930 |
super(invoker); |
4537 | 931 |
this.target = target; |
932 |
this.exType = exType; |
|
933 |
this.catcher = catcher; |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
934 |
} |
4537 | 935 |
@Override |
936 |
public String toString() { |
|
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
937 |
return addTypeString(target, this); |
4537 | 938 |
} |
939 |
private Object invoke_V(Object... av) throws Throwable { |
|
940 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
941 |
return target.invokeExact(av); |
4537 | 942 |
} catch (Throwable t) { |
943 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
944 |
return catcher.invokeExact(t, av); |
4537 | 945 |
} |
946 |
} |
|
947 |
private Object invoke_L0() throws Throwable { |
|
948 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
949 |
return target.invokeExact(); |
4537 | 950 |
} catch (Throwable t) { |
951 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
952 |
return catcher.invokeExact(t); |
4537 | 953 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
954 |
} |
4537 | 955 |
private Object invoke_L1(Object a0) throws Throwable { |
956 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
957 |
return target.invokeExact(a0); |
4537 | 958 |
} catch (Throwable t) { |
959 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
960 |
return catcher.invokeExact(t, a0); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
961 |
} |
4537 | 962 |
} |
963 |
private Object invoke_L2(Object a0, Object a1) throws Throwable { |
|
964 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
965 |
return target.invokeExact(a0, a1); |
4537 | 966 |
} catch (Throwable t) { |
967 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
968 |
return catcher.invokeExact(t, a0, a1); |
4537 | 969 |
} |
970 |
} |
|
971 |
private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable { |
|
972 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
973 |
return target.invokeExact(a0, a1, a2); |
4537 | 974 |
} catch (Throwable t) { |
975 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
976 |
return catcher.invokeExact(t, a0, a1, a2); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
977 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
978 |
} |
4537 | 979 |
private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { |
980 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
981 |
return target.invokeExact(a0, a1, a2, a3); |
4537 | 982 |
} catch (Throwable t) { |
983 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
984 |
return catcher.invokeExact(t, a0, a1, a2, a3); |
4537 | 985 |
} |
986 |
} |
|
987 |
private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { |
|
988 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
989 |
return target.invokeExact(a0, a1, a2, a3, a4); |
4537 | 990 |
} catch (Throwable t) { |
991 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
992 |
return catcher.invokeExact(t, a0, a1, a2, a3, a4); |
4537 | 993 |
} |
994 |
} |
|
995 |
private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { |
|
996 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
997 |
return target.invokeExact(a0, a1, a2, a3, a4, a5); |
4537 | 998 |
} catch (Throwable t) { |
999 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
1000 |
return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5); |
4537 | 1001 |
} |
1002 |
} |
|
1003 |
private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { |
|
1004 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
1005 |
return target.invokeExact(a0, a1, a2, a3, a4, a5, a6); |
4537 | 1006 |
} catch (Throwable t) { |
1007 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
1008 |
return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6); |
4537 | 1009 |
} |
1010 |
} |
|
1011 |
private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { |
|
1012 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
1013 |
return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7); |
4537 | 1014 |
} catch (Throwable t) { |
1015 |
if (!exType.isInstance(t)) throw t; |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
1016 |
return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6, a7); |
4537 | 1017 |
} |
1018 |
} |
|
1019 |
static MethodHandle[] makeInvokes() { |
|
1020 |
ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>(); |
|
1021 |
MethodHandles.Lookup lookup = IMPL_LOOKUP; |
|
1022 |
for (;;) { |
|
1023 |
int nargs = invokes.size(); |
|
1024 |
String name = "invoke_L"+nargs; |
|
1025 |
MethodHandle invoke = null; |
|
1026 |
try { |
|
1027 |
invoke = lookup.findVirtual(GuardWithCatch.class, name, MethodType.genericMethodType(nargs)); |
|
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
1028 |
} catch (ReflectiveOperationException ex) { |
4537 | 1029 |
} |
1030 |
if (invoke == null) break; |
|
1031 |
invokes.add(invoke); |
|
1032 |
} |
|
1033 |
assert(invokes.size() == 9); // current number of methods |
|
1034 |
return invokes.toArray(new MethodHandle[0]); |
|
1035 |
}; |
|
1036 |
static final MethodHandle[] INVOKES = makeInvokes(); |
|
1037 |
// For testing use this: |
|
1038 |
//static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2); |
|
1039 |
static final MethodHandle VARARGS_INVOKE; |
|
1040 |
static { |
|
1041 |
try { |
|
1042 |
VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithCatch.class, "invoke_V", MethodType.genericMethodType(0, true)); |
|
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
1043 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
1044 |
throw uncaughtException(ex); |
4537 | 1045 |
} |
1046 |
} |
|
1047 |
} |
|
1048 |
||
1049 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1050 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1051 |
MethodHandle makeGuardWithCatch(MethodHandle target, |
4537 | 1052 |
Class<? extends Throwable> exType, |
1053 |
MethodHandle catcher) { |
|
1054 |
MethodType type = target.type(); |
|
1055 |
MethodType ctype = catcher.type(); |
|
1056 |
int nargs = type.parameterCount(); |
|
1057 |
if (nargs < GuardWithCatch.INVOKES.length) { |
|
1058 |
MethodType gtype = type.generic(); |
|
1059 |
MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1060 |
MethodHandle gtarget = convertArguments(target, gtype, type, null); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1061 |
MethodHandle gcatcher = convertArguments(catcher, gcatchType, ctype, null); |
4537 | 1062 |
MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher); |
1063 |
if (gtarget == null || gcatcher == null || gguard == null) return null; |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1064 |
return convertArguments(gguard, type, gtype, null); |
4537 | 1065 |
} else { |
1066 |
MethodType gtype = MethodType.genericMethodType(0, true); |
|
1067 |
MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class); |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1068 |
MethodHandle gtarget = spreadArguments(target, gtype, 0); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1069 |
MethodHandle gcatcher = spreadArguments(catcher, gcatchType, 1); |
4537 | 1070 |
MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher); |
1071 |
if (gtarget == null || gcatcher == null || gguard == null) return null; |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1072 |
return collectArguments(gguard, type, 0, null); |
4537 | 1073 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
1074 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
1075 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1076 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1077 |
MethodHandle throwException(MethodType type) { |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1078 |
return AdapterMethodHandle.makeRetypeRaw(type, throwException()); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
1079 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
1080 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1081 |
static MethodHandle THROW_EXCEPTION; |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1082 |
static MethodHandle throwException() { |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1083 |
if (THROW_EXCEPTION != null) return THROW_EXCEPTION; |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
1084 |
try { |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
1085 |
THROW_EXCEPTION |
4537 | 1086 |
= IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException", |
1087 |
MethodType.methodType(Empty.class, Throwable.class)); |
|
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
1088 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
1089 |
throw new RuntimeException(ex); |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
1090 |
} |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1091 |
return THROW_EXCEPTION; |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
1092 |
} |
4537 | 1093 |
static <T extends Throwable> Empty throwException(T t) throws T { throw t; } |
1094 |
||
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
1095 |
// Linkage support: |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1096 |
static void registerBootstrap(Class<?> callerClass, MethodHandle bootstrapMethod) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
1097 |
MethodHandleNatives.registerBootstrap(callerClass, bootstrapMethod); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
1098 |
} |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1099 |
static MethodHandle getBootstrap(Class<?> callerClass) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
1100 |
return MethodHandleNatives.getBootstrap(callerClass); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
1101 |
} |
7554
8a0ad9757002
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
7052
diff
changeset
|
1102 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1103 |
static MethodHandle asVarargsCollector(MethodHandle target, Class<?> arrayType) { |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
1104 |
return AdapterMethodHandle.makeVarargsCollector(target, arrayType); |
7554
8a0ad9757002
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
7052
diff
changeset
|
1105 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
1106 |
} |