author | twisti |
Wed, 09 Nov 2011 00:46:13 -0800 | |
changeset 11007 | 09d3dddac781 |
parent 10615 | 7e211ad476ca |
child 11534 | 9949ffb8eb3a |
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 |
|
8822
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
26 |
package java.lang.invoke; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
27 |
|
8822
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
28 |
import sun.invoke.util.VerifyType; |
9780
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
29 |
import java.security.AccessController; |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
30 |
import java.security.PrivilegedAction; |
4537 | 31 |
import java.util.ArrayList; |
32 |
import java.util.Arrays; |
|
33 |
import java.util.Collections; |
|
34 |
import java.util.HashMap; |
|
35 |
import java.util.List; |
|
8822
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
36 |
import sun.invoke.empty.Empty; |
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
37 |
import sun.invoke.util.ValueConversions; |
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
38 |
import sun.invoke.util.Wrapper; |
4537 | 39 |
import sun.misc.Unsafe; |
8822
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
40 |
import static java.lang.invoke.MethodHandleStatics.*; |
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
41 |
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
42 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
43 |
/** |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
44 |
* Trusted implementation code for MethodHandle. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
45 |
* @author jrose |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
46 |
*/ |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
47 |
/*non-public*/ abstract class MethodHandleImpl { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
48 |
/// Factory methods to create method handles: |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
49 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
50 |
private static final MemberName.Factory LOOKUP = MemberName.Factory.INSTANCE; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
51 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
52 |
static void initStatics() { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
53 |
// Trigger preceding sequence. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
54 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
55 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
56 |
/** Look up a given method. |
8822
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
57 |
* Callable only from sun.invoke and related packages. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
58 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
59 |
* 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
|
60 |
* 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
|
61 |
* <p> |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
62 |
* 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
|
63 |
* 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
|
64 |
* 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
|
65 |
* the lookup class or a subclass. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
66 |
* @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
|
67 |
* @param member Resolved method or constructor to call. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
68 |
* @param name Name of the desired method. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
69 |
* @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
|
70 |
* @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
|
71 |
* @param lookupClass access-check relative to this class |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
72 |
* @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
|
73 |
* @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
|
74 |
*/ |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
75 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
76 |
MethodHandle findMethod(MemberName method, |
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
77 |
boolean doDispatch, Class<?> lookupClass) throws IllegalAccessException { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
78 |
MethodType mtype = method.getMethodType(); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
79 |
if (!method.isStatic()) { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
80 |
// 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
|
81 |
// (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
|
82 |
Class<?> recvType = method.getDeclaringClass(); |
4537 | 83 |
mtype = mtype.insertParameterTypes(0, recvType); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
84 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
85 |
DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
86 |
if (!mh.isValid()) |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
87 |
throw method.makeAccessException("no direct method handle", lookupClass); |
5723
a58a0eed34b0
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
5722
diff
changeset
|
88 |
assert(mh.type() == mtype); |
8345
9e2483e6cfab
7013417: JSR 292 needs to support variadic method handle calls
jrose
parents:
7556
diff
changeset
|
89 |
if (!method.isVarargs()) |
9e2483e6cfab
7013417: JSR 292 needs to support variadic method handle calls
jrose
parents:
7556
diff
changeset
|
90 |
return mh; |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
91 |
int argc = mtype.parameterCount(); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
92 |
if (argc != 0) { |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
93 |
Class<?> arrayType = mtype.parameterType(argc-1); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
94 |
if (arrayType.isArray()) |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
95 |
return AdapterMethodHandle.makeVarargsCollector(mh, arrayType); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
96 |
} |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
97 |
throw method.makeAccessException("cannot make variable arity", null); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
98 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
99 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
100 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
101 |
MethodHandle makeAllocator(MethodHandle rawConstructor) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
102 |
MethodType rawConType = rawConstructor.type(); |
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
103 |
Class<?> allocateClass = rawConType.parameterType(0); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
104 |
// Wrap the raw (unsafe) constructor with the allocation of a suitable object. |
10082 | 105 |
assert(AdapterMethodHandle.canCollectArguments(rawConType, MethodType.methodType(allocateClass), 0, true)); |
106 |
// allocator(arg...) |
|
107 |
// [fold]=> cookedConstructor(obj=allocate(C), arg...) |
|
108 |
// [dup,collect]=> identity(obj, void=rawConstructor(obj, arg...)) |
|
109 |
MethodHandle returner = MethodHandles.identity(allocateClass); |
|
110 |
MethodType ctype = rawConType.insertParameterTypes(0, allocateClass).changeReturnType(allocateClass); |
|
111 |
MethodHandle cookedConstructor = AdapterMethodHandle.makeCollectArguments(returner, rawConstructor, 1, false); |
|
112 |
assert(cookedConstructor.type().equals(ctype)); |
|
113 |
ctype = ctype.dropParameterTypes(0, 1); |
|
114 |
cookedConstructor = AdapterMethodHandle.makeCollectArguments(cookedConstructor, returner, 0, true); |
|
115 |
MethodHandle allocator = new AllocateObject(allocateClass); |
|
116 |
// allocate() => new C(void) |
|
117 |
assert(allocator.type().equals(MethodType.methodType(allocateClass))); |
|
118 |
ctype = ctype.dropParameterTypes(0, 1); |
|
119 |
MethodHandle fold = foldArguments(cookedConstructor, ctype, 0, allocator); |
|
120 |
return fold; |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
121 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
122 |
|
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
123 |
static final class AllocateObject<C> extends BoundMethodHandle { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
124 |
private static final Unsafe unsafe = Unsafe.getUnsafe(); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
125 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
126 |
private final Class<C> allocateClass; |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
127 |
|
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
128 |
// for allocation only: |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
129 |
private AllocateObject(Class<C> allocateClass) { |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
130 |
super(ALLOCATE.asType(MethodType.methodType(allocateClass, AllocateObject.class))); |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
131 |
this.allocateClass = allocateClass; |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
132 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
133 |
@SuppressWarnings("unchecked") |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
134 |
private C allocate() throws InstantiationException { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
135 |
return (C) unsafe.allocateInstance(allocateClass); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
136 |
} |
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
137 |
static final MethodHandle ALLOCATE; |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
138 |
static { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
139 |
try { |
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
140 |
ALLOCATE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "allocate", MethodType.genericMethodType(0)); |
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
8346
diff
changeset
|
141 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
142 |
throw uncaughtException(ex); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
143 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
144 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
145 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
146 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
147 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
148 |
MethodHandle accessField(MemberName member, boolean isSetter, |
4537 | 149 |
Class<?> lookupClass) { |
150 |
// 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
|
151 |
MethodHandle mh = new FieldAccessor(member, isSetter); |
4537 | 152 |
return mh; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
153 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
154 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
155 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
156 |
MethodHandle accessArrayElement(Class<?> arrayClass, boolean isSetter) { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
157 |
if (!arrayClass.isArray()) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
158 |
throw newIllegalArgumentException("not an array: "+arrayClass); |
4537 | 159 |
Class<?> elemClass = arrayClass.getComponentType(); |
160 |
MethodHandle[] mhs = FieldAccessor.ARRAY_CACHE.get(elemClass); |
|
161 |
if (mhs == null) { |
|
162 |
if (!FieldAccessor.doCache(elemClass)) |
|
163 |
return FieldAccessor.ahandle(arrayClass, isSetter); |
|
164 |
mhs = new MethodHandle[] { |
|
165 |
FieldAccessor.ahandle(arrayClass, false), |
|
166 |
FieldAccessor.ahandle(arrayClass, true) |
|
167 |
}; |
|
168 |
if (mhs[0].type().parameterType(0) == Class.class) { |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
169 |
mhs[0] = mhs[0].bindTo(elemClass); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
170 |
mhs[1] = mhs[1].bindTo(elemClass); |
4537 | 171 |
} |
172 |
synchronized (FieldAccessor.ARRAY_CACHE) {} // memory barrier |
|
173 |
FieldAccessor.ARRAY_CACHE.put(elemClass, mhs); |
|
174 |
} |
|
175 |
return mhs[isSetter ? 1 : 0]; |
|
176 |
} |
|
177 |
||
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
178 |
static final class FieldAccessor<C,V> extends BoundMethodHandle { |
4537 | 179 |
private static final Unsafe unsafe = Unsafe.getUnsafe(); |
180 |
final Object base; // for static refs only |
|
181 |
final long offset; |
|
182 |
final String name; |
|
183 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
184 |
FieldAccessor(MemberName field, boolean isSetter) { |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
185 |
super(fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic())); |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
186 |
this.offset = (long) field.getVMIndex(); |
4537 | 187 |
this.name = field.getName(); |
188 |
this.base = staticBase(field); |
|
189 |
} |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
190 |
@Override |
9731
d0f7a3e441c4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
9730
diff
changeset
|
191 |
String debugString() { return addTypeString(name, this); } |
4537 | 192 |
|
193 |
int getFieldI(C obj) { return unsafe.getInt(obj, offset); } |
|
194 |
void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); } |
|
195 |
long getFieldJ(C obj) { return unsafe.getLong(obj, offset); } |
|
196 |
void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); } |
|
197 |
float getFieldF(C obj) { return unsafe.getFloat(obj, offset); } |
|
198 |
void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); } |
|
199 |
double getFieldD(C obj) { return unsafe.getDouble(obj, offset); } |
|
200 |
void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); } |
|
201 |
boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); } |
|
202 |
void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); } |
|
203 |
byte getFieldB(C obj) { return unsafe.getByte(obj, offset); } |
|
204 |
void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); } |
|
205 |
short getFieldS(C obj) { return unsafe.getShort(obj, offset); } |
|
206 |
void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); } |
|
207 |
char getFieldC(C obj) { return unsafe.getChar(obj, offset); } |
|
208 |
void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); } |
|
209 |
@SuppressWarnings("unchecked") |
|
210 |
V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); } |
|
211 |
@SuppressWarnings("unchecked") |
|
212 |
void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); } |
|
213 |
// cast (V) is OK here, since we wrap convertArguments around the MH. |
|
214 |
||
9780
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
215 |
static Object staticBase(final MemberName field) { |
4537 | 216 |
if (!field.isStatic()) return null; |
9780
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
217 |
return AccessController.doPrivileged(new PrivilegedAction<Object>() { |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
218 |
public Object run() { |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
219 |
try { |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
220 |
Class c = field.getDeclaringClass(); |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
221 |
// FIXME: Should not have to create 'f' to get this value. |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
222 |
java.lang.reflect.Field f = c.getDeclaredField(field.getName()); |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
223 |
return unsafe.staticFieldBase(f); |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
224 |
} catch (NoSuchFieldException ee) { |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
225 |
throw uncaughtException(ee); |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
226 |
} |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
227 |
} |
6fc3b49cfee4
7050328: (jsr-292) findConstructor throws ExceptionInInitializerError if run under SecurityManager
jrose
parents:
9752
diff
changeset
|
228 |
}); |
4537 | 229 |
} |
230 |
||
231 |
int getStaticI() { return unsafe.getInt(base, offset); } |
|
232 |
void setStaticI(int x) { unsafe.putInt(base, offset, x); } |
|
233 |
long getStaticJ() { return unsafe.getLong(base, offset); } |
|
234 |
void setStaticJ(long x) { unsafe.putLong(base, offset, x); } |
|
235 |
float getStaticF() { return unsafe.getFloat(base, offset); } |
|
236 |
void setStaticF(float x) { unsafe.putFloat(base, offset, x); } |
|
237 |
double getStaticD() { return unsafe.getDouble(base, offset); } |
|
238 |
void setStaticD(double x) { unsafe.putDouble(base, offset, x); } |
|
239 |
boolean getStaticZ() { return unsafe.getBoolean(base, offset); } |
|
240 |
void setStaticZ(boolean x) { unsafe.putBoolean(base, offset, x); } |
|
241 |
byte getStaticB() { return unsafe.getByte(base, offset); } |
|
242 |
void setStaticB(byte x) { unsafe.putByte(base, offset, x); } |
|
243 |
short getStaticS() { return unsafe.getShort(base, offset); } |
|
244 |
void setStaticS(short x) { unsafe.putShort(base, offset, x); } |
|
245 |
char getStaticC() { return unsafe.getChar(base, offset); } |
|
246 |
void setStaticC(char x) { unsafe.putChar(base, offset, x); } |
|
247 |
V getStaticL() { return (V) unsafe.getObject(base, offset); } |
|
248 |
void setStaticL(V x) { unsafe.putObject(base, offset, x); } |
|
249 |
||
250 |
static String fname(Class<?> vclass, boolean isSetter, boolean isStatic) { |
|
251 |
String stem; |
|
252 |
if (!isStatic) |
|
253 |
stem = (!isSetter ? "getField" : "setField"); |
|
254 |
else |
|
255 |
stem = (!isSetter ? "getStatic" : "setStatic"); |
|
256 |
return stem + Wrapper.basicTypeChar(vclass); |
|
257 |
} |
|
258 |
static MethodType ftype(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) { |
|
259 |
MethodType type; |
|
260 |
if (!isStatic) { |
|
261 |
if (!isSetter) |
|
262 |
return MethodType.methodType(vclass, cclass); |
|
263 |
else |
|
264 |
return MethodType.methodType(void.class, cclass, vclass); |
|
265 |
} else { |
|
266 |
if (!isSetter) |
|
267 |
return MethodType.methodType(vclass); |
|
268 |
else |
|
269 |
return MethodType.methodType(void.class, vclass); |
|
270 |
} |
|
271 |
} |
|
272 |
static MethodHandle fhandle(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) { |
|
273 |
String name = FieldAccessor.fname(vclass, isSetter, isStatic); |
|
274 |
if (cclass.isPrimitive()) throw newIllegalArgumentException("primitive "+cclass); |
|
275 |
Class<?> ecclass = Object.class; //erase this type |
|
276 |
Class<?> evclass = vclass; |
|
277 |
if (!evclass.isPrimitive()) evclass = Object.class; |
|
278 |
MethodType type = FieldAccessor.ftype(ecclass, evclass, isSetter, isStatic); |
|
279 |
MethodHandle mh; |
|
280 |
try { |
|
281 |
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
|
282 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
283 |
throw uncaughtException(ex); |
4537 | 284 |
} |
285 |
if (evclass != vclass || (!isStatic && ecclass != cclass)) { |
|
286 |
MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic); |
|
287 |
strongType = strongType.insertParameterTypes(0, FieldAccessor.class); |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
288 |
mh = convertArguments(mh, strongType, 0); |
4537 | 289 |
} |
290 |
return mh; |
|
291 |
} |
|
292 |
||
293 |
/// Support for array element access |
|
294 |
static final HashMap<Class<?>, MethodHandle[]> ARRAY_CACHE = |
|
295 |
new HashMap<Class<?>, MethodHandle[]>(); |
|
296 |
// FIXME: Cache on the classes themselves, not here. |
|
297 |
static boolean doCache(Class<?> elemClass) { |
|
298 |
if (elemClass.isPrimitive()) return true; |
|
299 |
ClassLoader cl = elemClass.getClassLoader(); |
|
300 |
return cl == null || cl == ClassLoader.getSystemClassLoader(); |
|
301 |
} |
|
302 |
static int getElementI(int[] a, int i) { return a[i]; } |
|
303 |
static void setElementI(int[] a, int i, int x) { a[i] = x; } |
|
304 |
static long getElementJ(long[] a, int i) { return a[i]; } |
|
305 |
static void setElementJ(long[] a, int i, long x) { a[i] = x; } |
|
306 |
static float getElementF(float[] a, int i) { return a[i]; } |
|
307 |
static void setElementF(float[] a, int i, float x) { a[i] = x; } |
|
308 |
static double getElementD(double[] a, int i) { return a[i]; } |
|
309 |
static void setElementD(double[] a, int i, double x) { a[i] = x; } |
|
310 |
static boolean getElementZ(boolean[] a, int i) { return a[i]; } |
|
311 |
static void setElementZ(boolean[] a, int i, boolean x) { a[i] = x; } |
|
312 |
static byte getElementB(byte[] a, int i) { return a[i]; } |
|
313 |
static void setElementB(byte[] a, int i, byte x) { a[i] = x; } |
|
314 |
static short getElementS(short[] a, int i) { return a[i]; } |
|
315 |
static void setElementS(short[] a, int i, short x) { a[i] = x; } |
|
316 |
static char getElementC(char[] a, int i) { return a[i]; } |
|
317 |
static void setElementC(char[] a, int i, char x) { a[i] = x; } |
|
318 |
static Object getElementL(Object[] a, int i) { return a[i]; } |
|
319 |
static void setElementL(Object[] a, int i, Object x) { a[i] = x; } |
|
320 |
static <V> V getElementL(Class<V[]> aclass, V[] a, int i) { return aclass.cast(a)[i]; } |
|
321 |
static <V> void setElementL(Class<V[]> aclass, V[] a, int i, V x) { aclass.cast(a)[i] = x; } |
|
322 |
||
323 |
static String aname(Class<?> aclass, boolean isSetter) { |
|
324 |
Class<?> vclass = aclass.getComponentType(); |
|
325 |
if (vclass == null) throw new IllegalArgumentException(); |
|
326 |
return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(vclass); |
|
327 |
} |
|
328 |
static MethodType atype(Class<?> aclass, boolean isSetter) { |
|
329 |
Class<?> vclass = aclass.getComponentType(); |
|
330 |
if (!isSetter) |
|
331 |
return MethodType.methodType(vclass, aclass, int.class); |
|
332 |
else |
|
333 |
return MethodType.methodType(void.class, aclass, int.class, vclass); |
|
334 |
} |
|
335 |
static MethodHandle ahandle(Class<?> aclass, boolean isSetter) { |
|
336 |
Class<?> vclass = aclass.getComponentType(); |
|
337 |
String name = FieldAccessor.aname(aclass, isSetter); |
|
338 |
Class<?> caclass = null; |
|
339 |
if (!vclass.isPrimitive() && vclass != Object.class) { |
|
340 |
caclass = aclass; |
|
341 |
aclass = Object[].class; |
|
342 |
vclass = Object.class; |
|
343 |
} |
|
344 |
MethodType type = FieldAccessor.atype(aclass, isSetter); |
|
345 |
if (caclass != null) |
|
346 |
type = type.insertParameterTypes(0, Class.class); |
|
347 |
MethodHandle mh; |
|
348 |
try { |
|
349 |
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
|
350 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
351 |
throw uncaughtException(ex); |
4537 | 352 |
} |
353 |
if (caclass != null) { |
|
354 |
MethodType strongType = FieldAccessor.atype(caclass, isSetter); |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
355 |
mh = mh.bindTo(caclass); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
356 |
mh = convertArguments(mh, strongType, 0); |
4537 | 357 |
} |
358 |
return mh; |
|
359 |
} |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
360 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
361 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
362 |
/** 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
|
363 |
* Callable only from MethodHandles. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
364 |
* @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
|
365 |
* @param target Any direct method handle. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
366 |
* @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
|
367 |
* @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
|
368 |
*/ |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
369 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
370 |
MethodHandle bindReceiver(MethodHandle target, Object receiver) { |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
371 |
if (receiver == null) return null; |
7554
8a0ad9757002
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
7052
diff
changeset
|
372 |
if (target instanceof AdapterMethodHandle && |
8a0ad9757002
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
7052
diff
changeset
|
373 |
((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
|
374 |
) { |
2764
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
375 |
Object info = MethodHandleNatives.getTargetInfo(target); |
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
376 |
if (info instanceof DirectMethodHandle) { |
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
377 |
DirectMethodHandle dmh = (DirectMethodHandle) info; |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
378 |
if (dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) { |
4537 | 379 |
MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0); |
380 |
MethodType newType = target.type().dropParameterTypes(0, 1); |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
381 |
return convertArguments(bmh, newType, bmh.type(), 0); |
4537 | 382 |
} |
2764
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
383 |
} |
2e45af54c0f9
6839839: access checking logic is wrong at three points in MethodHandles
jrose
parents:
2707
diff
changeset
|
384 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
385 |
if (target instanceof DirectMethodHandle) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
386 |
return new BoundMethodHandle((DirectMethodHandle)target, receiver, 0); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
387 |
return null; // let caller try something else |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
388 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
389 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
390 |
/** 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
|
391 |
* Callable only from MethodHandles. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
392 |
* @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
|
393 |
* @param target Any method handle. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
394 |
* @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
|
395 |
* @return a suitable BoundMethodHandle |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
396 |
*/ |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
397 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
398 |
MethodHandle bindArgument(MethodHandle target, int argnum, Object receiver) { |
4537 | 399 |
return new BoundMethodHandle(target, receiver, argnum); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
400 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
401 |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
402 |
static MethodHandle permuteArguments(MethodHandle target, |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
403 |
MethodType newType, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
404 |
MethodType oldType, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
405 |
int[] permutationOrNull) { |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
406 |
assert(oldType.parameterCount() == target.type().parameterCount()); |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
407 |
int outargs = oldType.parameterCount(), inargs = newType.parameterCount(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
408 |
if (permutationOrNull.length != outargs) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
409 |
throw newIllegalArgumentException("wrong number of arguments in permutation"); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
410 |
// Make the individual outgoing argument types match up first. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
411 |
Class<?>[] callTypeArgs = new Class<?>[outargs]; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
412 |
for (int i = 0; i < outargs; i++) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
413 |
callTypeArgs[i] = newType.parameterType(permutationOrNull[i]); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
414 |
MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
415 |
target = convertArguments(target, callType, oldType, 0); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
416 |
assert(target != null); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
417 |
oldType = target.type(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
418 |
List<Integer> goal = new ArrayList<Integer>(); // i*TOKEN |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
419 |
List<Integer> state = new ArrayList<Integer>(); // i*TOKEN |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
420 |
List<Integer> drops = new ArrayList<Integer>(); // not tokens |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
421 |
List<Integer> dups = new ArrayList<Integer>(); // not tokens |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
422 |
final int TOKEN = 10; // to mark items which are symbolic only |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
423 |
// state represents the argument values coming into target |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
424 |
for (int i = 0; i < outargs; i++) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
425 |
state.add(permutationOrNull[i] * TOKEN); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
426 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
427 |
// goal represents the desired state |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
428 |
for (int i = 0; i < inargs; i++) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
429 |
if (state.contains(i * TOKEN)) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
430 |
goal.add(i * TOKEN); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
431 |
} else { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
432 |
// adapter must initially drop all unused arguments |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
433 |
drops.add(i); |
4537 | 434 |
} |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
435 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
436 |
// detect duplications |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
437 |
while (state.size() > goal.size()) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
438 |
for (int i2 = 0; i2 < state.size(); i2++) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
439 |
int arg1 = state.get(i2); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
440 |
int i1 = state.indexOf(arg1); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
441 |
if (i1 != i2) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
442 |
// found duplicate occurrence at i2 |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
443 |
int arg2 = (inargs++) * TOKEN; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
444 |
state.set(i2, arg2); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
445 |
dups.add(goal.indexOf(arg1)); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
446 |
goal.add(arg2); |
4537 | 447 |
} |
448 |
} |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
449 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
450 |
assert(state.size() == goal.size()); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
451 |
int size = goal.size(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
452 |
while (!state.equals(goal)) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
453 |
// Look for a maximal sequence of adjacent misplaced arguments, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
454 |
// and try to rotate them into place. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
455 |
int bestRotArg = -10 * TOKEN, bestRotLen = 0; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
456 |
int thisRotArg = -10 * TOKEN, thisRotLen = 0; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
457 |
for (int i = 0; i < size; i++) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
458 |
int arg = state.get(i); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
459 |
// Does this argument match the current run? |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
460 |
if (arg == thisRotArg + TOKEN) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
461 |
thisRotArg = arg; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
462 |
thisRotLen += 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
463 |
if (bestRotLen < thisRotLen) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
464 |
bestRotLen = thisRotLen; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
465 |
bestRotArg = thisRotArg; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
466 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
467 |
} else { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
468 |
// The old sequence (if any) stops here. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
469 |
thisRotLen = 0; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
470 |
thisRotArg = -10 * TOKEN; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
471 |
// But maybe a new one starts here also. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
472 |
int wantArg = goal.get(i); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
473 |
final int MAX_ARG_ROTATION = AdapterMethodHandle.MAX_ARG_ROTATION; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
474 |
if (arg != wantArg && |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
475 |
arg >= wantArg - TOKEN * MAX_ARG_ROTATION && |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
476 |
arg <= wantArg + TOKEN * MAX_ARG_ROTATION) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
477 |
thisRotArg = arg; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
478 |
thisRotLen = 1; |
4537 | 479 |
} |
480 |
} |
|
481 |
} |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
482 |
if (bestRotLen >= 2) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
483 |
// Do a rotation if it can improve argument positioning |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
484 |
// by at least 2 arguments. This is not always optimal, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
485 |
// but it seems to catch common cases. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
486 |
int dstEnd = state.indexOf(bestRotArg); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
487 |
int srcEnd = goal.indexOf(bestRotArg); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
488 |
int rotBy = dstEnd - srcEnd; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
489 |
int dstBeg = dstEnd - (bestRotLen - 1); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
490 |
int srcBeg = srcEnd - (bestRotLen - 1); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
491 |
assert((dstEnd | dstBeg | srcEnd | srcBeg) >= 0); // no negs |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
492 |
// Make a span which covers both source and destination. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
493 |
int rotBeg = Math.min(dstBeg, srcBeg); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
494 |
int rotEnd = Math.max(dstEnd, srcEnd); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
495 |
int score = 0; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
496 |
for (int i = rotBeg; i <= rotEnd; i++) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
497 |
if ((int)state.get(i) != (int)goal.get(i)) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
498 |
score += 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
499 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
500 |
List<Integer> rotSpan = state.subList(rotBeg, rotEnd+1); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
501 |
Collections.rotate(rotSpan, -rotBy); // reverse direction |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
502 |
for (int i = rotBeg; i <= rotEnd; i++) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
503 |
if ((int)state.get(i) != (int)goal.get(i)) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
504 |
score -= 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
505 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
506 |
if (score >= 2) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
507 |
// Improved at least two argument positions. Do it. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
508 |
List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray()); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
509 |
Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
510 |
MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
511 |
MethodHandle nextTarget |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
512 |
= AdapterMethodHandle.makeRotateArguments(rotType, target, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
513 |
rotBeg, rotSpan.size(), rotBy); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
514 |
if (nextTarget != null) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
515 |
//System.out.println("Rot: "+rotSpan+" by "+rotBy); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
516 |
target = nextTarget; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
517 |
oldType = rotType; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
518 |
continue; |
4537 | 519 |
} |
520 |
} |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
521 |
// Else de-rotate, and drop through to the swap-fest. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
522 |
Collections.rotate(rotSpan, rotBy); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
523 |
} |
4537 | 524 |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
525 |
// Now swap like the wind! |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
526 |
List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray()); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
527 |
for (int i = 0; i < size; i++) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
528 |
// What argument do I want here? |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
529 |
int arg = goal.get(i); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
530 |
if (arg != state.get(i)) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
531 |
// Where is it now? |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
532 |
int j = state.indexOf(arg); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
533 |
Collections.swap(ptypes, i, j); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
534 |
MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
535 |
target = AdapterMethodHandle.makeSwapArguments(swapType, target, i, j); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
536 |
if (target == null) throw newIllegalArgumentException("cannot swap"); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
537 |
assert(target.type() == swapType); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
538 |
oldType = swapType; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
539 |
Collections.swap(state, i, j); |
4537 | 540 |
} |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
541 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
542 |
// One pass of swapping must finish the job. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
543 |
assert(state.equals(goal)); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
544 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
545 |
while (!dups.isEmpty()) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
546 |
// Grab a contiguous trailing sequence of dups. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
547 |
int grab = dups.size() - 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
548 |
int dupArgPos = dups.get(grab), dupArgCount = 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
549 |
while (grab - 1 >= 0) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
550 |
int dup0 = dups.get(grab - 1); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
551 |
if (dup0 != dupArgPos - 1) break; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
552 |
dupArgPos -= 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
553 |
dupArgCount += 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
554 |
grab -= 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
555 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
556 |
//if (dupArgCount > 1) System.out.println("Dup: "+dups.subList(grab, dups.size())); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
557 |
dups.subList(grab, dups.size()).clear(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
558 |
// In the new target type drop that many args from the tail: |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
559 |
List<Class<?>> ptypes = oldType.parameterList(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
560 |
ptypes = ptypes.subList(0, ptypes.size() - dupArgCount); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
561 |
MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
562 |
target = AdapterMethodHandle.makeDupArguments(dupType, target, dupArgPos, dupArgCount); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
563 |
if (target == null) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
564 |
throw newIllegalArgumentException("cannot dup"); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
565 |
oldType = target.type(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
566 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
567 |
while (!drops.isEmpty()) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
568 |
// Grab a contiguous initial sequence of drops. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
569 |
int dropArgPos = drops.get(0), dropArgCount = 1; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
570 |
while (dropArgCount < drops.size()) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
571 |
int drop1 = drops.get(dropArgCount); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
572 |
if (drop1 != dropArgPos + dropArgCount) break; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
573 |
dropArgCount += 1; |
4537 | 574 |
} |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
575 |
//if (dropArgCount > 1) System.out.println("Drop: "+drops.subList(0, dropArgCount)); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
576 |
drops.subList(0, dropArgCount).clear(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
577 |
List<Class<?>> dropTypes = newType.parameterList() |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
578 |
.subList(dropArgPos, dropArgPos + dropArgCount); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
579 |
MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
580 |
target = AdapterMethodHandle.makeDropArguments(dropType, target, dropArgPos, dropArgCount); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
581 |
if (target == null) throw newIllegalArgumentException("cannot drop"); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
582 |
oldType = target.type(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
583 |
} |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
584 |
target = convertArguments(target, newType, oldType, 0); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
585 |
assert(target != null); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
586 |
return target; |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
587 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
588 |
|
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
589 |
/*non-public*/ static |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
590 |
MethodHandle convertArguments(MethodHandle target, MethodType newType, int level) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
591 |
MethodType oldType = target.type(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
592 |
if (oldType.equals(newType)) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
593 |
return target; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
594 |
assert(level > 1 || oldType.isConvertibleTo(newType)); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
595 |
MethodHandle retFilter = null; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
596 |
Class<?> oldRT = oldType.returnType(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
597 |
Class<?> newRT = newType.returnType(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
598 |
if (!VerifyType.isNullConversion(oldRT, newRT)) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
599 |
if (oldRT == void.class) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
600 |
Wrapper wrap = newRT.isPrimitive() ? Wrapper.forPrimitiveType(newRT) : Wrapper.OBJECT; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
601 |
retFilter = ValueConversions.zeroConstantFunction(wrap); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
602 |
} else { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
603 |
retFilter = MethodHandles.identity(newRT); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
604 |
retFilter = convertArguments(retFilter, retFilter.type().changeParameterType(0, oldRT), level); |
4537 | 605 |
} |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
606 |
newType = newType.changeReturnType(oldRT); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
607 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
608 |
MethodHandle res = null; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
609 |
Exception ex = null; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
610 |
try { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
611 |
res = convertArguments(target, newType, oldType, level); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
612 |
} catch (IllegalArgumentException ex1) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
613 |
ex = ex1; |
4537 | 614 |
} |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
615 |
if (res == null) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
616 |
WrongMethodTypeException wmt = new WrongMethodTypeException("cannot convert to "+newType+": "+target); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
617 |
wmt.initCause(ex); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
618 |
throw wmt; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
619 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
620 |
if (retFilter != null) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
621 |
res = MethodHandles.filterReturnValue(res, retFilter); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
622 |
return res; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
623 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
624 |
|
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
625 |
static MethodHandle convertArguments(MethodHandle target, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
626 |
MethodType newType, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
627 |
MethodType oldType, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
628 |
int level) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
629 |
assert(oldType.parameterCount() == target.type().parameterCount()); |
4537 | 630 |
if (newType == oldType) |
631 |
return target; |
|
632 |
if (oldType.parameterCount() != newType.parameterCount()) |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
633 |
throw newIllegalArgumentException("mismatched parameter count", oldType, newType); |
10082 | 634 |
return AdapterMethodHandle.makePairwiseConvert(newType, target, level); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
635 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
636 |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
637 |
static MethodHandle spreadArguments(MethodHandle target, Class<?> arrayType, int arrayLength) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
638 |
MethodType oldType = target.type(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
639 |
int nargs = oldType.parameterCount(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
640 |
int keepPosArgs = nargs - arrayLength; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
641 |
MethodType newType = oldType |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
642 |
.dropParameterTypes(keepPosArgs, nargs) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
643 |
.insertParameterTypes(keepPosArgs, arrayType); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
644 |
return spreadArguments(target, newType, keepPosArgs, arrayType, arrayLength); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
645 |
} |
9859
47e26ad535c4
7052202: JSR 292: Crash in sun.invoke.util.ValueConversions.fillArray
jrose
parents:
9780
diff
changeset
|
646 |
// called internally only |
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
647 |
static MethodHandle spreadArgumentsFromPos(MethodHandle target, MethodType newType, int spreadArgPos) { |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
648 |
int arrayLength = target.type().parameterCount() - spreadArgPos; |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
649 |
return spreadArguments(target, newType, spreadArgPos, Object[].class, arrayLength); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
650 |
} |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
651 |
static MethodHandle spreadArguments(MethodHandle target, |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
652 |
MethodType newType, |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
653 |
int spreadArgPos, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
654 |
Class<?> arrayType, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
655 |
int arrayLength) { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
656 |
// 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
|
657 |
MethodType oldType = target.type(); |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
658 |
// spread the last argument of newType to oldType |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
659 |
assert(arrayLength == oldType.parameterCount() - spreadArgPos); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
660 |
assert(newType.parameterType(spreadArgPos) == arrayType); |
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
661 |
return AdapterMethodHandle.makeSpreadArguments(newType, target, arrayType, spreadArgPos, arrayLength); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
662 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
663 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
664 |
static MethodHandle collectArguments(MethodHandle target, |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
665 |
int collectArg, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
666 |
MethodHandle collector) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
667 |
MethodType type = target.type(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
668 |
Class<?> collectType = collector.type().returnType(); |
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
669 |
assert(collectType != void.class); // else use foldArguments |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
670 |
if (collectType != type.parameterType(collectArg)) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
671 |
target = target.asType(type.changeParameterType(collectArg, collectType)); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
672 |
MethodType newType = type |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
673 |
.dropParameterTypes(collectArg, collectArg+1) |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
674 |
.insertParameterTypes(collectArg, collector.type().parameterArray()); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
675 |
return collectArguments(target, newType, collectArg, collector); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
676 |
} |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
677 |
static MethodHandle collectArguments(MethodHandle target, |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
678 |
MethodType newType, |
4537 | 679 |
int collectArg, |
680 |
MethodHandle collector) { |
|
681 |
MethodType oldType = target.type(); // (a...,c)=>r |
|
682 |
// newType // (a..., b...)=>r |
|
683 |
MethodType colType = collector.type(); // (b...)=>c |
|
684 |
// oldType // (a..., b...)=>r |
|
685 |
assert(newType.parameterCount() == collectArg + colType.parameterCount()); |
|
686 |
assert(oldType.parameterCount() == collectArg + 1); |
|
10082 | 687 |
assert(AdapterMethodHandle.canCollectArguments(oldType, colType, collectArg, false)); |
688 |
return AdapterMethodHandle.makeCollectArguments(target, collector, collectArg, false); |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
689 |
} |
4537 | 690 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
691 |
static MethodHandle filterArgument(MethodHandle target, |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
692 |
int pos, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
693 |
MethodHandle filter) { |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
694 |
MethodType ttype = target.type(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
695 |
MethodType ftype = filter.type(); |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
696 |
assert(ftype.parameterCount() == 1); |
10082 | 697 |
return AdapterMethodHandle.makeCollectArguments(target, filter, pos, false); |
4537 | 698 |
} |
699 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
700 |
static MethodHandle foldArguments(MethodHandle target, |
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
701 |
MethodType newType, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
702 |
int foldPos, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
703 |
MethodHandle combiner) { |
4537 | 704 |
MethodType oldType = target.type(); |
705 |
MethodType ctype = combiner.type(); |
|
10082 | 706 |
assert(AdapterMethodHandle.canCollectArguments(oldType, ctype, foldPos, true)); |
707 |
return AdapterMethodHandle.makeCollectArguments(target, combiner, foldPos, true); |
|
4537 | 708 |
} |
709 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
710 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
711 |
MethodHandle dropArguments(MethodHandle target, |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
712 |
MethodType newType, int argnum) { |
4537 | 713 |
int drops = newType.parameterCount() - target.type().parameterCount(); |
10082 | 714 |
return AdapterMethodHandle.makeDropArguments(newType, target, argnum, drops); |
4537 | 715 |
} |
716 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
717 |
static |
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
718 |
MethodHandle selectAlternative(boolean testResult, MethodHandle target, MethodHandle fallback) { |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
719 |
return testResult ? target : fallback; |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
720 |
} |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
721 |
|
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
722 |
static MethodHandle SELECT_ALTERNATIVE; |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
723 |
static MethodHandle selectAlternative() { |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
724 |
if (SELECT_ALTERNATIVE != null) return SELECT_ALTERNATIVE; |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
725 |
try { |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
726 |
SELECT_ALTERNATIVE |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
727 |
= IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "selectAlternative", |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
728 |
MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class)); |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
729 |
} catch (ReflectiveOperationException ex) { |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
730 |
throw new RuntimeException(ex); |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
731 |
} |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
732 |
return SELECT_ALTERNATIVE; |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
733 |
} |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
734 |
|
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
735 |
static |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
736 |
MethodHandle makeGuardWithTest(MethodHandle test, |
4537 | 737 |
MethodHandle target, |
738 |
MethodHandle fallback) { |
|
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
739 |
// gwt(arg...) |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
740 |
// [fold]=> continueAfterTest(z=test(arg...), arg...) |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
741 |
// [filter]=> (tf=select(z))(arg...) |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
742 |
// where select(z) = select(z, t, f).bindTo(t, f) => z ? t f |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
743 |
// [tailcall]=> tf(arg...) |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
744 |
assert(test.type().returnType() == boolean.class); |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
745 |
MethodType targetType = target.type(); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
9731
diff
changeset
|
746 |
MethodType foldTargetType = targetType.insertParameterTypes(0, boolean.class); |
10082 | 747 |
assert(AdapterMethodHandle.canCollectArguments(foldTargetType, test.type(), 0, true)); |
748 |
// working backwards, as usual: |
|
749 |
assert(target.type().equals(fallback.type())); |
|
750 |
MethodHandle tailcall = MethodHandles.exactInvoker(target.type()); |
|
751 |
MethodHandle select = selectAlternative(); |
|
10615 | 752 |
select = bindArgument(select, 2, CountingMethodHandle.wrap(fallback)); |
753 |
select = bindArgument(select, 1, CountingMethodHandle.wrap(target)); |
|
10082 | 754 |
// select(z: boolean) => (z ? target : fallback) |
755 |
MethodHandle filter = filterArgument(tailcall, 0, select); |
|
756 |
assert(filter.type().parameterType(0) == boolean.class); |
|
757 |
MethodHandle fold = foldArguments(filter, filter.type().dropParameterTypes(0, 1), 0, test); |
|
758 |
return fold; |
|
4537 | 759 |
} |
760 |
||
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
761 |
private static class GuardWithCatch extends BoundMethodHandle { |
4537 | 762 |
private final MethodHandle target; |
763 |
private final Class<? extends Throwable> exType; |
|
764 |
private final MethodHandle catcher; |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
765 |
GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { |
4537 | 766 |
this(INVOKES[target.type().parameterCount()], target, exType, catcher); |
767 |
} |
|
9646
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
768 |
// FIXME: Build the control flow out of foldArguments. |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
769 |
GuardWithCatch(MethodHandle invoker, |
5ebbe5ab084f
6939861: JVM should handle more conversion operations
jrose
parents:
8822
diff
changeset
|
770 |
MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
771 |
super(invoker); |
4537 | 772 |
this.target = target; |
773 |
this.exType = exType; |
|
774 |
this.catcher = catcher; |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
775 |
} |
4537 | 776 |
@Override |
9731
d0f7a3e441c4
7044892: JSR 292: API entry points sometimes throw the wrong exceptions or doesn't throw the expected one
jrose
parents:
9730
diff
changeset
|
777 |
String debugString() { |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
7554
diff
changeset
|
778 |
return addTypeString(target, this); |
4537 | 779 |
} |
780 |
private Object invoke_V(Object... av) throws Throwable { |
|
781 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
782 |
return target.invokeExact(av); |
4537 | 783 |
} catch (Throwable t) { |
784 |
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
|
785 |
return catcher.invokeExact(t, av); |
4537 | 786 |
} |
787 |
} |
|
788 |
private Object invoke_L0() throws Throwable { |
|
789 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
790 |
return target.invokeExact(); |
4537 | 791 |
} catch (Throwable t) { |
792 |
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
|
793 |
return catcher.invokeExact(t); |
4537 | 794 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
795 |
} |
4537 | 796 |
private Object invoke_L1(Object a0) throws Throwable { |
797 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
798 |
return target.invokeExact(a0); |
4537 | 799 |
} catch (Throwable t) { |
800 |
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
|
801 |
return catcher.invokeExact(t, a0); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
802 |
} |
4537 | 803 |
} |
804 |
private Object invoke_L2(Object a0, Object a1) throws Throwable { |
|
805 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
806 |
return target.invokeExact(a0, a1); |
4537 | 807 |
} catch (Throwable t) { |
808 |
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
|
809 |
return catcher.invokeExact(t, a0, a1); |
4537 | 810 |
} |
811 |
} |
|
812 |
private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable { |
|
813 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
814 |
return target.invokeExact(a0, a1, a2); |
4537 | 815 |
} catch (Throwable t) { |
816 |
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
|
817 |
return catcher.invokeExact(t, a0, a1, a2); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
818 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
819 |
} |
4537 | 820 |
private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { |
821 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
822 |
return target.invokeExact(a0, a1, a2, a3); |
4537 | 823 |
} catch (Throwable t) { |
824 |
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
|
825 |
return catcher.invokeExact(t, a0, a1, a2, a3); |
4537 | 826 |
} |
827 |
} |
|
828 |
private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { |
|
829 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
830 |
return target.invokeExact(a0, a1, a2, a3, a4); |
4537 | 831 |
} catch (Throwable t) { |
832 |
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
|
833 |
return catcher.invokeExact(t, a0, a1, a2, a3, a4); |
4537 | 834 |
} |
835 |
} |
|
836 |
private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { |
|
837 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
838 |
return target.invokeExact(a0, a1, a2, a3, a4, a5); |
4537 | 839 |
} catch (Throwable t) { |
840 |
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
|
841 |
return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5); |
4537 | 842 |
} |
843 |
} |
|
844 |
private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { |
|
845 |
try { |
|
7556
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, a1, a2, a3, a4, a5, a6); |
4537 | 847 |
} catch (Throwable t) { |
848 |
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
|
849 |
return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6); |
4537 | 850 |
} |
851 |
} |
|
852 |
private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { |
|
853 |
try { |
|
7556
4a5711d43948
6979327: method handle invocation should use casts instead of type parameters to specify return type
jrose
parents:
7555
diff
changeset
|
854 |
return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7); |
4537 | 855 |
} catch (Throwable t) { |
856 |
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
|
857 |
return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6, a7); |
4537 | 858 |
} |
859 |
} |
|
860 |
static MethodHandle[] makeInvokes() { |
|
861 |
ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>(); |
|
862 |
MethodHandles.Lookup lookup = IMPL_LOOKUP; |
|
863 |
for (;;) { |
|
864 |
int nargs = invokes.size(); |
|
865 |
String name = "invoke_L"+nargs; |
|
866 |
MethodHandle invoke = null; |
|
867 |
try { |
|
868 |
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
|
869 |
} catch (ReflectiveOperationException ex) { |
4537 | 870 |
} |
871 |
if (invoke == null) break; |
|
872 |
invokes.add(invoke); |
|
873 |
} |
|
874 |
assert(invokes.size() == 9); // current number of methods |
|
875 |
return invokes.toArray(new MethodHandle[0]); |
|
876 |
}; |
|
877 |
static final MethodHandle[] INVOKES = makeInvokes(); |
|
878 |
// For testing use this: |
|
879 |
//static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2); |
|
880 |
static final MethodHandle VARARGS_INVOKE; |
|
881 |
static { |
|
882 |
try { |
|
883 |
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
|
884 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
885 |
throw uncaughtException(ex); |
4537 | 886 |
} |
887 |
} |
|
888 |
} |
|
889 |
||
890 |
||
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
891 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
892 |
MethodHandle makeGuardWithCatch(MethodHandle target, |
4537 | 893 |
Class<? extends Throwable> exType, |
894 |
MethodHandle catcher) { |
|
895 |
MethodType type = target.type(); |
|
896 |
MethodType ctype = catcher.type(); |
|
897 |
int nargs = type.parameterCount(); |
|
898 |
if (nargs < GuardWithCatch.INVOKES.length) { |
|
899 |
MethodType gtype = type.generic(); |
|
900 |
MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class); |
|
9859
47e26ad535c4
7052202: JSR 292: Crash in sun.invoke.util.ValueConversions.fillArray
jrose
parents:
9780
diff
changeset
|
901 |
// Note: convertArguments(...2) avoids interface casts present in convertArguments(...0) |
47e26ad535c4
7052202: JSR 292: Crash in sun.invoke.util.ValueConversions.fillArray
jrose
parents:
9780
diff
changeset
|
902 |
MethodHandle gtarget = convertArguments(target, gtype, type, 2); |
47e26ad535c4
7052202: JSR 292: Crash in sun.invoke.util.ValueConversions.fillArray
jrose
parents:
9780
diff
changeset
|
903 |
MethodHandle gcatcher = convertArguments(catcher, gcatchType, ctype, 2); |
4537 | 904 |
MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher); |
905 |
if (gtarget == null || gcatcher == null || gguard == null) return null; |
|
9859
47e26ad535c4
7052202: JSR 292: Crash in sun.invoke.util.ValueConversions.fillArray
jrose
parents:
9780
diff
changeset
|
906 |
return convertArguments(gguard, type, gtype, 2); |
4537 | 907 |
} else { |
908 |
MethodType gtype = MethodType.genericMethodType(0, true); |
|
909 |
MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class); |
|
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
910 |
MethodHandle gtarget = spreadArgumentsFromPos(target, gtype, 0); |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
911 |
catcher = catcher.asType(ctype.changeParameterType(0, Throwable.class)); |
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
912 |
MethodHandle gcatcher = spreadArgumentsFromPos(catcher, gcatchType, 1); |
4537 | 913 |
MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher); |
914 |
if (gtarget == null || gcatcher == null || gguard == null) return null; |
|
9730
e4b334d47f4b
7032850: MethodHandle.invokeGeneric throws unspecified RuntimeException if parameterized method is called
jrose
parents:
9646
diff
changeset
|
915 |
return collectArguments(gguard, type, 0, ValueConversions.varargsArray(nargs)).asType(type); |
4537 | 916 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
917 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
918 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
919 |
static |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
920 |
MethodHandle throwException(MethodType type) { |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
921 |
return AdapterMethodHandle.makeRetypeRaw(type, throwException()); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
922 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
923 |
|
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
924 |
static MethodHandle THROW_EXCEPTION; |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
925 |
static MethodHandle throwException() { |
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
926 |
if (THROW_EXCEPTION != null) return THROW_EXCEPTION; |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
927 |
try { |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
928 |
THROW_EXCEPTION |
4537 | 929 |
= IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException", |
930 |
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
|
931 |
} catch (ReflectiveOperationException ex) { |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
932 |
throw new RuntimeException(ex); |
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
933 |
} |
8821
2836ee97ee27
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
8347
diff
changeset
|
934 |
return THROW_EXCEPTION; |
7052
963a5baf2ba3
6980096: JSR 292 reflective lookup should throw checked exceptions
jrose
parents:
5725
diff
changeset
|
935 |
} |
4537 | 936 |
static <T extends Throwable> Empty throwException(T t) throws T { throw t; } |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
937 |
} |