author | jlaskey |
Thu, 21 Jun 2018 08:58:59 -0300 | |
changeset 50695 | 36ca515343e0 |
parent 47216 | 71c04702a3d5 |
permissions | -rw-r--r-- |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
1 |
/* |
35407
204abe4d8cbc
8147591: Revisit Collection.toArray(new T[size]) calls in nashorn and dynalink code
mhaupt
parents:
34447
diff
changeset
|
2 |
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
4 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
7 |
* published by the Free Software Foundation. Oracle designates this |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
8 |
* particular file as subject to the "Classpath" exception as provided |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
10 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
15 |
* accompanied this code). |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
16 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License version |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
20 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
22 |
* or visit www.oracle.com if you need additional information or have any |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
23 |
* questions. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
24 |
*/ |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
25 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
26 |
/* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
27 |
* This file is available under and governed by the GNU General Public |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
28 |
* License version 2 only, as published by the Free Software Foundation. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
29 |
* However, the following notice accompanied the original version of this |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
30 |
* file, and Oracle licenses the original version of this file under the BSD |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
31 |
* license: |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
32 |
*/ |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
33 |
/* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
34 |
Copyright 2009-2013 Attila Szegedi |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
35 |
|
50695 | 36 |
Redistribution and use in source and binary forms, with or without |
37 |
modification, are permitted provided that the following conditions are |
|
38 |
met: |
|
39 |
* Redistributions of source code must retain the above copyright |
|
40 |
notice, this list of conditions and the following disclaimer. |
|
41 |
* Redistributions in binary form must reproduce the above copyright |
|
42 |
notice, this list of conditions and the following disclaimer in the |
|
43 |
documentation and/or other materials provided with the distribution. |
|
44 |
* Neither the name of the copyright holder nor the names of |
|
45 |
contributors may be used to endorse or promote products derived from |
|
46 |
this software without specific prior written permission. |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
47 |
|
50695 | 48 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
49 |
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|
50 |
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
|
51 |
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER |
|
52 |
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
53 |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
54 |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
|
55 |
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
|
56 |
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
|
57 |
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
|
58 |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
59 |
*/ |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
60 |
|
34447
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
61 |
package jdk.dynalink; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
62 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
63 |
import java.lang.invoke.MethodHandle; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
64 |
import java.lang.invoke.MethodHandles; |
33335
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
65 |
import java.lang.invoke.MethodHandles.Lookup; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
66 |
import java.lang.invoke.MethodType; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
67 |
import java.lang.invoke.WrongMethodTypeException; |
33341
cc9fa3638714
8139905: Add a convenience AccessControlContext factory
attila
parents:
33337
diff
changeset
|
68 |
import java.security.AccessControlContext; |
19455 | 69 |
import java.security.AccessController; |
70 |
import java.security.PrivilegedAction; |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
71 |
import java.util.LinkedList; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
72 |
import java.util.List; |
33335
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
73 |
import java.util.function.Supplier; |
34447
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
74 |
import jdk.dynalink.internal.AccessControlContextFactory; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
75 |
import jdk.dynalink.linker.ConversionComparator; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
76 |
import jdk.dynalink.linker.ConversionComparator.Comparison; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
77 |
import jdk.dynalink.linker.GuardedInvocation; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
78 |
import jdk.dynalink.linker.GuardingTypeConverterFactory; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
79 |
import jdk.dynalink.linker.LinkerServices; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
80 |
import jdk.dynalink.linker.MethodTypeConversionStrategy; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33341
diff
changeset
|
81 |
import jdk.dynalink.linker.support.TypeUtilities; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
82 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
83 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
84 |
* A factory for type converters. This class is the main implementation behind the |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
85 |
* {@link LinkerServices#asType(MethodHandle, MethodType)}. It manages the known {@link GuardingTypeConverterFactory} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
86 |
* instances and creates appropriate converters for method handles. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
87 |
*/ |
33330
35531ae624ef
8139304: Remove elaborate call site descriptor class hierarchy and factory for them. Remove AutoDiscovery, DefaultPrelinkFilter, and BottomGuardingDynamicLinker as they can be inlined into DynamicLinkerFactory. Remove CallerSensitiveDetector as it can be inlined into AbstractJavaLinker. Make ClassMap non-public.
attila
parents:
33007
diff
changeset
|
88 |
final class TypeConverterFactory { |
33341
cc9fa3638714
8139905: Add a convenience AccessControlContext factory
attila
parents:
33337
diff
changeset
|
89 |
private static final AccessControlContext GET_CLASS_LOADER_CONTEXT = |
cc9fa3638714
8139905: Add a convenience AccessControlContext factory
attila
parents:
33337
diff
changeset
|
90 |
AccessControlContextFactory.createAccessControlContext("getClassLoader"); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
91 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
92 |
private final GuardingTypeConverterFactory[] factories; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
93 |
private final ConversionComparator[] comparators; |
27360 | 94 |
private final MethodTypeConversionStrategy autoConversionStrategy; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
95 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
96 |
private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<ClassMap<MethodHandle>>() { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
97 |
@Override |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
98 |
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) { |
19455 | 99 |
return new ClassMap<MethodHandle>(getClassLoader(sourceType)) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
100 |
@Override |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
101 |
protected MethodHandle computeValue(final Class<?> targetType) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
102 |
try { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
103 |
return createConverter(sourceType, targetType); |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
104 |
} catch (final RuntimeException e) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
105 |
throw e; |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
106 |
} catch (final Exception e) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
107 |
throw new RuntimeException(e); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
108 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
109 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
110 |
}; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
111 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
112 |
}; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
113 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
114 |
private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<ClassMap<MethodHandle>>() { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
115 |
@Override |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
116 |
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) { |
19455 | 117 |
return new ClassMap<MethodHandle>(getClassLoader(sourceType)) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
118 |
@Override |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
119 |
protected MethodHandle computeValue(final Class<?> targetType) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
120 |
if(!canAutoConvert(sourceType, targetType)) { |
22669 | 121 |
final MethodHandle converter = getCacheableTypeConverter(sourceType, targetType); |
122 |
if(converter != IDENTITY_CONVERSION) { |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
123 |
return converter; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
124 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
125 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
126 |
return IDENTITY_CONVERSION.asType(MethodType.methodType(targetType, sourceType)); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
127 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
128 |
}; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
129 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
130 |
}; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
131 |
|
22669 | 132 |
private final ClassValue<ClassMap<Boolean>> canConvert = new ClassValue<ClassMap<Boolean>>() { |
133 |
@Override |
|
134 |
protected ClassMap<Boolean> computeValue(final Class<?> sourceType) { |
|
135 |
return new ClassMap<Boolean>(getClassLoader(sourceType)) { |
|
136 |
@Override |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
137 |
protected Boolean computeValue(final Class<?> targetType) { |
22669 | 138 |
try { |
139 |
return getTypeConverterNull(sourceType, targetType) != null; |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
140 |
} catch (final RuntimeException e) { |
22669 | 141 |
throw e; |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
142 |
} catch (final Exception e) { |
22669 | 143 |
throw new RuntimeException(e); |
144 |
} |
|
145 |
} |
|
146 |
}; |
|
147 |
} |
|
148 |
}; |
|
149 |
||
31549
b627094c5649
8130734: Apply transformations found by netbeans Refactor->Inspect and transform menu
sundar
parents:
27360
diff
changeset
|
150 |
private static ClassLoader getClassLoader(final Class<?> clazz) { |
19455 | 151 |
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { |
152 |
@Override |
|
153 |
public ClassLoader run() { |
|
154 |
return clazz.getClassLoader(); |
|
155 |
} |
|
33341
cc9fa3638714
8139905: Add a convenience AccessControlContext factory
attila
parents:
33337
diff
changeset
|
156 |
}, GET_CLASS_LOADER_CONTEXT); |
19455 | 157 |
} |
158 |
||
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
159 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
160 |
* Creates a new type converter factory from the available {@link GuardingTypeConverterFactory} instances. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
161 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
162 |
* @param factories the {@link GuardingTypeConverterFactory} instances to compose. |
27360 | 163 |
* @param autoConversionStrategy conversion strategy for automatic type conversions. After |
164 |
* {@link #asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)} has applied all custom |
|
165 |
* conversions to a method handle, it still needs to effect |
|
166 |
* {@link TypeUtilities#isMethodInvocationConvertible(Class, Class) method invocation conversions} that |
|
167 |
* can usually be automatically applied as per |
|
168 |
* {@link java.lang.invoke.MethodHandle#asType(java.lang.invoke.MethodType)}. |
|
169 |
* However, sometimes language runtimes will want to customize even those conversions for their own call |
|
170 |
* sites. A typical example is allowing unboxing of null return values, which is by default prohibited by |
|
171 |
* ordinary {@code MethodHandles.asType}. In this case, a language runtime can install its own custom |
|
172 |
* automatic conversion strategy, that can deal with null values. Note that when the strategy's |
|
173 |
* {@link MethodTypeConversionStrategy#asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)} |
|
174 |
* is invoked, the custom language conversions will already have been applied to the method handle, so by |
|
175 |
* design the difference between the handle's current method type and the desired final type will always |
|
176 |
* only be ones that can be subjected to method invocation conversions. Can be null, in which case no |
|
177 |
* custom strategy is employed. |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
178 |
*/ |
33330
35531ae624ef
8139304: Remove elaborate call site descriptor class hierarchy and factory for them. Remove AutoDiscovery, DefaultPrelinkFilter, and BottomGuardingDynamicLinker as they can be inlined into DynamicLinkerFactory. Remove CallerSensitiveDetector as it can be inlined into AbstractJavaLinker. Make ClassMap non-public.
attila
parents:
33007
diff
changeset
|
179 |
TypeConverterFactory(final Iterable<? extends GuardingTypeConverterFactory> factories, |
27360 | 180 |
final MethodTypeConversionStrategy autoConversionStrategy) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
181 |
final List<GuardingTypeConverterFactory> l = new LinkedList<>(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
182 |
final List<ConversionComparator> c = new LinkedList<>(); |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
183 |
for(final GuardingTypeConverterFactory factory: factories) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
184 |
l.add(factory); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
185 |
if(factory instanceof ConversionComparator) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
186 |
c.add((ConversionComparator)factory); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
187 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
188 |
} |
35407
204abe4d8cbc
8147591: Revisit Collection.toArray(new T[size]) calls in nashorn and dynalink code
mhaupt
parents:
34447
diff
changeset
|
189 |
this.factories = l.toArray(new GuardingTypeConverterFactory[0]); |
204abe4d8cbc
8147591: Revisit Collection.toArray(new T[size]) calls in nashorn and dynalink code
mhaupt
parents:
34447
diff
changeset
|
190 |
this.comparators = c.toArray(new ConversionComparator[0]); |
27360 | 191 |
this.autoConversionStrategy = autoConversionStrategy; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
192 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
193 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
194 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
195 |
* Similar to {@link MethodHandle#asType(MethodType)} except it also hooks in method handles produced by |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
196 |
* {@link GuardingTypeConverterFactory} implementations, providing for language-specific type coercing of |
27360 | 197 |
* parameters. For all conversions that are not a JLS method invocation conversion it'll insert |
198 |
* {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with composite filters |
|
199 |
* provided by {@link GuardingTypeConverterFactory} implementations. For the remaining JLS method invocation |
|
200 |
* conversions, it will invoke {@link MethodTypeConversionStrategy#asType(MethodHandle, MethodType)} first |
|
201 |
* if an automatic conversion strategy was specified in the |
|
202 |
* {@link #TypeConverterFactory(Iterable, MethodTypeConversionStrategy) constructor}, and finally apply |
|
203 |
* {@link MethodHandle#asType(MethodType)} for any remaining conversions. |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
204 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
205 |
* @param handle target method handle |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
206 |
* @param fromType the types of source arguments |
27360 | 207 |
* @return a method handle that is a suitable combination of {@link MethodHandle#asType(MethodType)}, |
208 |
* {@link MethodTypeConversionStrategy#asType(MethodHandle, MethodType)}, and |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
209 |
* {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)} with |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
210 |
* {@link GuardingTypeConverterFactory} produced type converters as filters. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
211 |
*/ |
33330
35531ae624ef
8139304: Remove elaborate call site descriptor class hierarchy and factory for them. Remove AutoDiscovery, DefaultPrelinkFilter, and BottomGuardingDynamicLinker as they can be inlined into DynamicLinkerFactory. Remove CallerSensitiveDetector as it can be inlined into AbstractJavaLinker. Make ClassMap non-public.
attila
parents:
33007
diff
changeset
|
212 |
MethodHandle asType(final MethodHandle handle, final MethodType fromType) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
213 |
MethodHandle newHandle = handle; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
214 |
final MethodType toType = newHandle.type(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
215 |
final int l = toType.parameterCount(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
216 |
if(l != fromType.parameterCount()) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
217 |
throw new WrongMethodTypeException("Parameter counts differ: " + handle.type() + " vs. " + fromType); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
218 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
219 |
int pos = 0; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
220 |
final List<MethodHandle> converters = new LinkedList<>(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
221 |
for(int i = 0; i < l; ++i) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
222 |
final Class<?> fromParamType = fromType.parameterType(i); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
223 |
final Class<?> toParamType = toType.parameterType(i); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
224 |
if(canAutoConvert(fromParamType, toParamType)) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
225 |
newHandle = applyConverters(newHandle, pos, converters); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
226 |
} else { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
227 |
final MethodHandle converter = getTypeConverterNull(fromParamType, toParamType); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
228 |
if(converter != null) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
229 |
if(converters.isEmpty()) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
230 |
pos = i; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
231 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
232 |
converters.add(converter); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
233 |
} else { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
234 |
newHandle = applyConverters(newHandle, pos, converters); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
235 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
236 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
237 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
238 |
newHandle = applyConverters(newHandle, pos, converters); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
239 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
240 |
// Convert return type |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
241 |
final Class<?> fromRetType = fromType.returnType(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
242 |
final Class<?> toRetType = toType.returnType(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
243 |
if(fromRetType != Void.TYPE && toRetType != Void.TYPE) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
244 |
if(!canAutoConvert(toRetType, fromRetType)) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
245 |
final MethodHandle converter = getTypeConverterNull(toRetType, fromRetType); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
246 |
if(converter != null) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
247 |
newHandle = MethodHandles.filterReturnValue(newHandle, converter); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
248 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
249 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
250 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
251 |
|
27360 | 252 |
// Give change to automatic conversion strategy, if one is present. |
253 |
final MethodHandle autoConvertedHandle = |
|
254 |
autoConversionStrategy != null ? autoConversionStrategy.asType(newHandle, fromType) : newHandle; |
|
255 |
||
256 |
// Do a final asType for any conversions that remain. |
|
257 |
return autoConvertedHandle.asType(fromType); |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
258 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
259 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
260 |
private static MethodHandle applyConverters(final MethodHandle handle, final int pos, final List<MethodHandle> converters) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
261 |
if(converters.isEmpty()) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
262 |
return handle; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
263 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
264 |
final MethodHandle newHandle = |
35407
204abe4d8cbc
8147591: Revisit Collection.toArray(new T[size]) calls in nashorn and dynalink code
mhaupt
parents:
34447
diff
changeset
|
265 |
MethodHandles.filterArguments(handle, pos, converters.toArray(new MethodHandle[0])); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
266 |
converters.clear(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
267 |
return newHandle; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
268 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
269 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
270 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
271 |
* Returns true if there might exist a conversion between the requested types (either an automatic JVM conversion, |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
272 |
* or one provided by any available {@link GuardingTypeConverterFactory}), or false if there definitely does not |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
273 |
* exist a conversion between the requested types. Note that returning true does not guarantee that the conversion |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
274 |
* will succeed at runtime (notably, if the "from" or "to" types are sufficiently generic), but returning false |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
275 |
* guarantees that it would fail. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
276 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
277 |
* @param from the source type for the conversion |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
278 |
* @param to the target type for the conversion |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
279 |
* @return true if there can be a conversion, false if there can not. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
280 |
*/ |
33330
35531ae624ef
8139304: Remove elaborate call site descriptor class hierarchy and factory for them. Remove AutoDiscovery, DefaultPrelinkFilter, and BottomGuardingDynamicLinker as they can be inlined into DynamicLinkerFactory. Remove CallerSensitiveDetector as it can be inlined into AbstractJavaLinker. Make ClassMap non-public.
attila
parents:
33007
diff
changeset
|
281 |
boolean canConvert(final Class<?> from, final Class<?> to) { |
31549
b627094c5649
8130734: Apply transformations found by netbeans Refactor->Inspect and transform menu
sundar
parents:
27360
diff
changeset
|
282 |
return canAutoConvert(from, to) || canConvert.get(from).get(to); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
283 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
284 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
285 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
286 |
* Determines which of the two type conversions from a source type to the two target types is preferred. This is |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
287 |
* used for dynamic overloaded method resolution. If the source type is convertible to exactly one target type with |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
288 |
* a method invocation conversion, it is chosen, otherwise available {@link ConversionComparator}s are consulted. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
289 |
* @param sourceType the source type. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
290 |
* @param targetType1 one potential target type |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
291 |
* @param targetType2 another potential target type. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
292 |
* @return one of Comparison constants that establish which - if any - of the target types is preferable for the |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
293 |
* conversion. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
294 |
*/ |
33330
35531ae624ef
8139304: Remove elaborate call site descriptor class hierarchy and factory for them. Remove AutoDiscovery, DefaultPrelinkFilter, and BottomGuardingDynamicLinker as they can be inlined into DynamicLinkerFactory. Remove CallerSensitiveDetector as it can be inlined into AbstractJavaLinker. Make ClassMap non-public.
attila
parents:
33007
diff
changeset
|
295 |
Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) { |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
296 |
for(final ConversionComparator comparator: comparators) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
297 |
final Comparison result = comparator.compareConversion(sourceType, targetType1, targetType2); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
298 |
if(result != Comparison.INDETERMINATE) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
299 |
return result; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
300 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
301 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
302 |
if(TypeUtilities.isMethodInvocationConvertible(sourceType, targetType1)) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
303 |
if(!TypeUtilities.isMethodInvocationConvertible(sourceType, targetType2)) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
304 |
return Comparison.TYPE_1_BETTER; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
305 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
306 |
} else if(TypeUtilities.isMethodInvocationConvertible(sourceType, targetType2)) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
307 |
return Comparison.TYPE_2_BETTER; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
308 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
309 |
return Comparison.INDETERMINATE; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
310 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
311 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
312 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
313 |
* Determines whether it's safe to perform an automatic conversion between the source and target class. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
314 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
315 |
* @param fromType convert from this class |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
316 |
* @param toType convert to this class |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
317 |
* @return true if it's safe to let MethodHandles.convertArguments() to handle this conversion. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
318 |
*/ |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
319 |
/*private*/ static boolean canAutoConvert(final Class<?> fromType, final Class<?> toType) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
320 |
return TypeUtilities.isMethodInvocationConvertible(fromType, toType); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
321 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
322 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
323 |
/*private*/ MethodHandle getCacheableTypeConverterNull(final Class<?> sourceType, final Class<?> targetType) { |
22669 | 324 |
final MethodHandle converter = getCacheableTypeConverter(sourceType, targetType); |
325 |
return converter == IDENTITY_CONVERSION ? null : converter; |
|
326 |
} |
|
327 |
||
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
328 |
/*private*/ MethodHandle getTypeConverterNull(final Class<?> sourceType, final Class<?> targetType) { |
22669 | 329 |
try { |
330 |
return getCacheableTypeConverterNull(sourceType, targetType); |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
331 |
} catch(final NotCacheableConverter e) { |
22669 | 332 |
return e.converter; |
333 |
} |
|
334 |
} |
|
335 |
||
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
336 |
/*private*/ MethodHandle getCacheableTypeConverter(final Class<?> sourceType, final Class<?> targetType) { |
22669 | 337 |
return converterMap.get(sourceType).get(targetType); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
338 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
339 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
340 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
341 |
* Given a source and target type, returns a method handle that converts between them. Never returns null; in worst |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
342 |
* case it will return an identity conversion (that might fail for some values at runtime). You can use this method |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
343 |
* if you have a piece of your program that is written in Java, and you need to reuse existing type conversion |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
344 |
* machinery in a non-invokedynamic context. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
345 |
* @param sourceType the type to convert from |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
346 |
* @param targetType the type to convert to |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
347 |
* @return a method handle performing the conversion. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
348 |
*/ |
33330
35531ae624ef
8139304: Remove elaborate call site descriptor class hierarchy and factory for them. Remove AutoDiscovery, DefaultPrelinkFilter, and BottomGuardingDynamicLinker as they can be inlined into DynamicLinkerFactory. Remove CallerSensitiveDetector as it can be inlined into AbstractJavaLinker. Make ClassMap non-public.
attila
parents:
33007
diff
changeset
|
349 |
MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) { |
22669 | 350 |
try { |
351 |
return converterIdentityMap.get(sourceType).get(targetType); |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
352 |
} catch(final NotCacheableConverter e) { |
22669 | 353 |
return e.converter; |
354 |
} |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
355 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
356 |
|
33335
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
357 |
private static class LookupSupplier implements Supplier<MethodHandles.Lookup> { |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
358 |
volatile boolean returnedLookup; |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
359 |
volatile boolean closed; |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
360 |
|
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
361 |
@Override |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
362 |
public Lookup get() { |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
363 |
if (closed) { |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
364 |
// Something held on to this supplier and tried to invoke it |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
365 |
// after we're done with it. |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
366 |
throw new IllegalStateException(); |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
367 |
} |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
368 |
final Lookup lookup = LinkerServicesImpl.getCurrentLookup(); |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
369 |
returnedLookup = true; |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
370 |
return lookup; |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
371 |
} |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
372 |
} |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
373 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24720
diff
changeset
|
374 |
/*private*/ MethodHandle createConverter(final Class<?> sourceType, final Class<?> targetType) throws Exception { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
375 |
final MethodType type = MethodType.methodType(targetType, sourceType); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
376 |
final MethodHandle identity = IDENTITY_CONVERSION.asType(type); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
377 |
MethodHandle last = identity; |
33335
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
378 |
|
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
379 |
final LookupSupplier lookupSupplier = new LookupSupplier(); |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
380 |
try { |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
381 |
for(int i = factories.length; i-- > 0;) { |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
382 |
final GuardedInvocation next = factories[i].convertToType(sourceType, targetType, lookupSupplier); |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
383 |
if(next != null) { |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
384 |
last = next.compose(last); |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
385 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
386 |
} |
33335
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
387 |
} finally { |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
388 |
lookupSupplier.closed = true; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
389 |
} |
33335
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
390 |
|
22669 | 391 |
if(last == identity) { |
392 |
return IDENTITY_CONVERSION; |
|
393 |
} |
|
33335
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
394 |
if(!lookupSupplier.returnedLookup) { |
22669 | 395 |
return last; |
396 |
} |
|
33335
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
397 |
// At least one of the consulted converter factories obtained the |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
398 |
// lookup, so we must presume the created converter is sensitive to the |
a46c85103868
8139756: Eliminate GuardedTypeConversion, DynamicLinker.getCurrentLinkRequest and its associated permission
attila
parents:
33333
diff
changeset
|
399 |
// lookup class and thus we will not cache it. |
22669 | 400 |
throw new NotCacheableConverter(last); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
401 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
402 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
403 |
/*private*/ static final MethodHandle IDENTITY_CONVERSION = MethodHandles.identity(Object.class); |
22669 | 404 |
|
24720 | 405 |
@SuppressWarnings("serial") |
22669 | 406 |
private static class NotCacheableConverter extends RuntimeException { |
407 |
final MethodHandle converter; |
|
408 |
||
409 |
NotCacheableConverter(final MethodHandle converter) { |
|
410 |
super("", null, false, false); |
|
411 |
this.converter = converter; |
|
412 |
} |
|
413 |
} |
|
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
414 |
} |