author | attila |
Thu, 14 Jan 2016 13:22:58 +0100 | |
changeset 34978 | e753c4c9f96f |
parent 34842 | c8054093d6e7 |
child 34979 | 03b189baa361 |
permissions | -rw-r--r-- |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
1 |
/* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
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 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
36 |
Licensed under both the Apache License, Version 2.0 (the "Apache License") |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
37 |
and the BSD License (the "BSD License"), with licensee being free to |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
38 |
choose either of the two at their discretion. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
39 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
40 |
You may not use this file except in compliance with either the Apache |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
41 |
License or the BSD License. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
42 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
43 |
If you choose to use this file in compliance with the Apache License, the |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
44 |
following notice applies to you: |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
45 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
46 |
You may obtain a copy of the Apache License at |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
47 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
48 |
http://www.apache.org/licenses/LICENSE-2.0 |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
49 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
50 |
Unless required by applicable law or agreed to in writing, software |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
51 |
distributed under the License is distributed on an "AS IS" BASIS, |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
52 |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
53 |
implied. See the License for the specific language governing |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
54 |
permissions and limitations under the License. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
55 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
56 |
If you choose to use this file in compliance with the BSD License, the |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
57 |
following notice applies to you: |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
58 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
59 |
Redistribution and use in source and binary forms, with or without |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
60 |
modification, are permitted provided that the following conditions are |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
61 |
met: |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
62 |
* Redistributions of source code must retain the above copyright |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
63 |
notice, this list of conditions and the following disclaimer. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
64 |
* Redistributions in binary form must reproduce the above copyright |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
65 |
notice, this list of conditions and the following disclaimer in the |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
66 |
documentation and/or other materials provided with the distribution. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
67 |
* Neither the name of the copyright holder nor the names of |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
68 |
contributors may be used to endorse or promote products derived from |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
69 |
this software without specific prior written permission. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
70 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
71 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
72 |
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
73 |
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
74 |
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
75 |
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
76 |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
77 |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
78 |
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
79 |
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
80 |
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
81 |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
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 |
|
34447
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
84 |
package jdk.dynalink.beans; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
85 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
86 |
import java.lang.invoke.MethodHandle; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
87 |
import java.lang.invoke.MethodHandles; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
88 |
import java.lang.invoke.MethodType; |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
89 |
import java.lang.reflect.AccessibleObject; |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
90 |
import java.lang.reflect.Constructor; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
91 |
import java.lang.reflect.Field; |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
92 |
import java.lang.reflect.Member; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
93 |
import java.lang.reflect.Method; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
94 |
import java.lang.reflect.Modifier; |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
95 |
import java.util.Arrays; |
18876
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
96 |
import java.util.Collections; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
97 |
import java.util.HashMap; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
98 |
import java.util.List; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
99 |
import java.util.Map; |
33688 | 100 |
import java.util.Set; |
34447
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
101 |
import jdk.dynalink.CallSiteDescriptor; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
102 |
import jdk.dynalink.CompositeOperation; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
103 |
import jdk.dynalink.NamedOperation; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
104 |
import jdk.dynalink.Operation; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
105 |
import jdk.dynalink.StandardOperation; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
106 |
import jdk.dynalink.beans.GuardedInvocationComponent.ValidationType; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
107 |
import jdk.dynalink.internal.InternalTypeUtilities; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
108 |
import jdk.dynalink.linker.GuardedInvocation; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
109 |
import jdk.dynalink.linker.GuardingDynamicLinker; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
110 |
import jdk.dynalink.linker.LinkRequest; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
111 |
import jdk.dynalink.linker.LinkerServices; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
112 |
import jdk.dynalink.linker.support.Guards; |
ec4c069f9436
8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents:
33688
diff
changeset
|
113 |
import jdk.dynalink.linker.support.Lookup; |
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
|
114 |
import sun.reflect.CallerSensitive; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
115 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
116 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
117 |
* A base class for both {@link StaticClassLinker} and {@link BeanLinker}. Deals with common aspects of property |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
118 |
* exposure and method calls for both static and instance facets of a class. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
119 |
*/ |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
120 |
abstract class AbstractJavaLinker implements GuardingDynamicLinker { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
121 |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
122 |
final Class<?> clazz; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
123 |
private final MethodHandle classGuard; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
124 |
private final MethodHandle assignableGuard; |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
125 |
private final Map<String, AnnotatedDynamicMethod> propertyGetters = new HashMap<>(); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
126 |
private final Map<String, DynamicMethod> propertySetters = new HashMap<>(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
127 |
private final Map<String, DynamicMethod> methods = new HashMap<>(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
128 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
129 |
AbstractJavaLinker(final Class<?> clazz, final MethodHandle classGuard) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
130 |
this(clazz, classGuard, classGuard); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
131 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
132 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
133 |
AbstractJavaLinker(final Class<?> clazz, final MethodHandle classGuard, final MethodHandle assignableGuard) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
134 |
this.clazz = clazz; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
135 |
this.classGuard = classGuard; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
136 |
this.assignableGuard = assignableGuard; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
137 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
138 |
final FacetIntrospector introspector = createFacetIntrospector(); |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
139 |
// Add methods and properties |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
140 |
for(final Method method: introspector.getMethods()) { |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
141 |
final String name = method.getName(); |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
142 |
// Add method |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
143 |
addMember(name, method, methods); |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
144 |
// Add the method as a property getter and/or setter |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
145 |
if(name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0) { |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
146 |
// Property getter |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
147 |
setPropertyGetter(method, 3); |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
148 |
} else if(name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0 && |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
149 |
method.getReturnType() == boolean.class) { |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
150 |
// Boolean property getter |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
151 |
setPropertyGetter(method, 2); |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
152 |
} else if(name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) { |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
153 |
// Property setter |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
154 |
addMember(decapitalize(name.substring(3)), method, propertySetters); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
155 |
} |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
156 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
157 |
|
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
158 |
// Add field getter/setters as property getters/setters. |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
159 |
for(final Field field: introspector.getFields()) { |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
160 |
final String name = field.getName(); |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
161 |
// Only add a property getter when one is not defined already as a getXxx()/isXxx() method. |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
162 |
if(!propertyGetters.containsKey(name)) { |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
163 |
setPropertyGetter(name, introspector.unreflectGetter(field), ValidationType.EXACT_CLASS); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
164 |
} |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
165 |
if(!(Modifier.isFinal(field.getModifiers()) || propertySetters.containsKey(name))) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
166 |
addMember(name, new SimpleDynamicMethod(introspector.unreflectSetter(field), clazz, name), |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
167 |
propertySetters); |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
168 |
} |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
169 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
170 |
|
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
171 |
// Add inner classes, but only those for which we don't hide a property with it |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
172 |
for(final Map.Entry<String, MethodHandle> innerClassSpec: introspector.getInnerClassGetters().entrySet()) { |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
173 |
final String name = innerClassSpec.getKey(); |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
174 |
if(!propertyGetters.containsKey(name)) { |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
175 |
setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
176 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
177 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
178 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
179 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
180 |
private static String decapitalize(final String str) { |
16267
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
181 |
assert str != null; |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
182 |
if(str.isEmpty()) { |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
183 |
return str; |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
184 |
} |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
185 |
|
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
186 |
final char c0 = str.charAt(0); |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
187 |
if(Character.isLowerCase(c0)) { |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
188 |
return str; |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
189 |
} |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
190 |
|
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
191 |
// If it has two consecutive upper-case characters, i.e. "URL", don't decapitalize |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
192 |
if(str.length() > 1 && Character.isUpperCase(str.charAt(1))) { |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
193 |
return str; |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
194 |
} |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
195 |
|
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
196 |
final char c[] = str.toCharArray(); |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
197 |
c[0] = Character.toLowerCase(c0); |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
198 |
return new String(c); |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
199 |
} |
cd471d62bb6a
8009143: Eliminate Dynalink dependency on java.beans
attila
parents:
16245
diff
changeset
|
200 |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
201 |
abstract FacetIntrospector createFacetIntrospector(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
202 |
|
33688 | 203 |
Set<String> getReadablePropertyNames() { |
18876
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
204 |
return getUnmodifiableKeys(propertyGetters); |
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
205 |
} |
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
206 |
|
33688 | 207 |
Set<String> getWritablePropertyNames() { |
18876
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
208 |
return getUnmodifiableKeys(propertySetters); |
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
209 |
} |
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
210 |
|
33688 | 211 |
Set<String> getMethodNames() { |
18876
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
212 |
return getUnmodifiableKeys(methods); |
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
213 |
} |
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
214 |
|
33688 | 215 |
private static Set<String> getUnmodifiableKeys(final Map<String, ?> m) { |
216 |
return Collections.unmodifiableSet(m.keySet()); |
|
18876
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
217 |
} |
ada98218aaae
8020324: Implement Object.bindProperties(target, source) for beans
attila
parents:
18841
diff
changeset
|
218 |
|
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
219 |
/** |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
220 |
* Sets the specified dynamic method to be the property getter for the specified property. Note that you can only |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
221 |
* use this when you're certain that the method handle does not belong to a caller-sensitive method. For properties |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
222 |
* that are caller-sensitive, you must use {@link #setPropertyGetter(String, SingleDynamicMethod, ValidationType)} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
223 |
* instead. |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
224 |
* @param name name of the property |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
225 |
* @param handle the method handle that implements the property getter |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
226 |
* @param validationType the validation type for the property |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
227 |
*/ |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
228 |
private void setPropertyGetter(final String name, final SingleDynamicMethod handle, final ValidationType validationType) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
229 |
propertyGetters.put(name, new AnnotatedDynamicMethod(handle, validationType)); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
230 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
231 |
|
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
232 |
/** |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
233 |
* Sets the specified reflective method to be the property getter for the specified property. |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
234 |
* @param getter the getter method |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
235 |
* @param prefixLen the getter prefix in the method name; should be 3 for getter names starting with "get" and 2 for |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
236 |
* names starting with "is". |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
237 |
*/ |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
238 |
private void setPropertyGetter(final Method getter, final int prefixLen) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
239 |
setPropertyGetter(decapitalize(getter.getName().substring(prefixLen)), createDynamicMethod( |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
240 |
getMostGenericGetter(getter)), ValidationType.INSTANCE_OF); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
241 |
} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
242 |
|
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
243 |
/** |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
244 |
* Sets the specified method handle to be the property getter for the specified property. Note that you can only |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
245 |
* use this when you're certain that the method handle does not belong to a caller-sensitive method. For properties |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
246 |
* that are caller-sensitive, you must use {@link #setPropertyGetter(String, SingleDynamicMethod, ValidationType)} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
247 |
* instead. |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
248 |
* @param name name of the property |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
249 |
* @param handle the method handle that implements the property getter |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
250 |
* @param validationType the validation type for the property |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
251 |
*/ |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
252 |
void setPropertyGetter(final String name, final MethodHandle handle, final ValidationType validationType) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
253 |
setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
254 |
} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
255 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
256 |
private void addMember(final String name, final AccessibleObject ao, final Map<String, DynamicMethod> methodMap) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
257 |
addMember(name, createDynamicMethod(ao), methodMap); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
258 |
} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
259 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
260 |
private void addMember(final String name, final SingleDynamicMethod method, final Map<String, DynamicMethod> methodMap) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
261 |
final DynamicMethod existingMethod = methodMap.get(name); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
262 |
final DynamicMethod newMethod = mergeMethods(method, existingMethod, clazz, name); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
263 |
if(newMethod != existingMethod) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
264 |
methodMap.put(name, newMethod); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
265 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
266 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
267 |
|
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
268 |
/** |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
269 |
* Given one or more reflective methods or constructors, creates a dynamic method that represents them all. The |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
270 |
* methods should represent all overloads of the same name (or all constructors of the class). |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
271 |
* @param members the reflective members |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
272 |
* @param clazz the class declaring the reflective members |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
273 |
* @param name the common name of the reflective members. |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
274 |
* @return a dynamic method representing all the specified reflective members. |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
275 |
*/ |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
276 |
static DynamicMethod createDynamicMethod(final Iterable<? extends AccessibleObject> members, final Class<?> clazz, final String name) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
277 |
DynamicMethod dynMethod = null; |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
278 |
for(final AccessibleObject method: members) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
279 |
dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
280 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
281 |
return dynMethod; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
282 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
283 |
|
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
284 |
/** |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
285 |
* Given a reflective method or a constructor, creates a dynamic method that represents it. This method will |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
286 |
* distinguish between caller sensitive and ordinary methods/constructors, and create appropriate caller sensitive |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
287 |
* dynamic method when needed. |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
288 |
* @param m the reflective member |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
289 |
* @return the single dynamic method representing the reflective member |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
290 |
*/ |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
291 |
private static SingleDynamicMethod createDynamicMethod(final AccessibleObject m) { |
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
|
292 |
if (m.isAnnotationPresent(CallerSensitive.class)) { |
27359
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
293 |
// Method has @CallerSensitive annotation |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
294 |
return new CallerSensitiveDynamicMethod(m); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
295 |
} |
27359
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
296 |
// Method has no @CallerSensitive annotation |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
297 |
final MethodHandle mh; |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
298 |
try { |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
299 |
mh = unreflectSafely(m); |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
300 |
} catch (final IllegalAccessError e) { |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
301 |
// java.lang.invoke can in some case conservatively treat as caller sensitive methods that aren't |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
302 |
// marked with the annotation. In this case, we'll fall back to treating it as caller sensitive. |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
303 |
return new CallerSensitiveDynamicMethod(m); |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
304 |
} |
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
305 |
// Proceed with non-caller sensitive |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
306 |
final Member member = (Member)m; |
27359
59d61197a3f3
8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents:
25865
diff
changeset
|
307 |
return new SimpleDynamicMethod(mh, member.getDeclaringClass(), member.getName(), m instanceof Constructor); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
308 |
} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
309 |
|
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
310 |
/** |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
311 |
* Unreflects a method handle from a Method or a Constructor using safe (zero-privilege) unreflection. Should be |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
312 |
* only used for methods and constructors that are not caller sensitive. If a caller sensitive method were |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
313 |
* unreflected through this mechanism, it would not be a security issue, but would be bound to the zero-privilege |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
314 |
* unreflector as its caller, and thus completely useless. |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
315 |
* @param m the method or constructor |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
316 |
* @return the method handle |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
317 |
*/ |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
318 |
private static MethodHandle unreflectSafely(final AccessibleObject m) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
319 |
if(m instanceof Method) { |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
320 |
final Method reflMethod = (Method)m; |
19093
49bb7e75b326
8021189: Prevent access to constructors of restricted classes
attila
parents:
19092
diff
changeset
|
321 |
final MethodHandle handle = Lookup.PUBLIC.unreflect(reflMethod); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
322 |
if(Modifier.isStatic(reflMethod.getModifiers())) { |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
323 |
return StaticClassIntrospector.editStaticMethodHandle(handle); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
324 |
} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
325 |
return handle; |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
326 |
} |
19093
49bb7e75b326
8021189: Prevent access to constructors of restricted classes
attila
parents:
19092
diff
changeset
|
327 |
return StaticClassIntrospector.editConstructorMethodHandle(Lookup.PUBLIC.unreflectConstructor((Constructor<?>)m)); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
328 |
} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
329 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
330 |
private static DynamicMethod mergeMethods(final SingleDynamicMethod method, final DynamicMethod existing, final Class<?> clazz, final String name) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
331 |
if(existing == null) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
332 |
return method; |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
333 |
} else if(existing.contains(method)) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
334 |
return existing; |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
335 |
} else if(existing instanceof SingleDynamicMethod) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
336 |
final OverloadedDynamicMethod odm = new OverloadedDynamicMethod(clazz, name); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
337 |
odm.addMethod(((SingleDynamicMethod)existing)); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
338 |
odm.addMethod(method); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
339 |
return odm; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
340 |
} else if(existing instanceof OverloadedDynamicMethod) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
341 |
((OverloadedDynamicMethod)existing).addMethod(method); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
342 |
return existing; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
343 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
344 |
throw new AssertionError(); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
345 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
346 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
347 |
@Override |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
348 |
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
349 |
throws Exception { |
33332
f180be6368d8
8139588: Remove concept of runtime context arguments, call site tokens, and link counts
attila
parents:
33331
diff
changeset
|
350 |
final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor(); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
351 |
|
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
352 |
// Handle NamedOperation(CALL_METHOD, name) separately |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
353 |
final Operation operation = callSiteDescriptor.getOperation(); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
354 |
if (operation instanceof NamedOperation) { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
355 |
final NamedOperation namedOperation = (NamedOperation)operation; |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
356 |
if (namedOperation.getBaseOperation() == StandardOperation.CALL_METHOD) { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
357 |
return createGuardedDynamicMethodInvocation(callSiteDescriptor, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
358 |
linkerServices, namedOperation.getName().toString(), methods); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
359 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
360 |
} |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
361 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
362 |
final GuardedInvocationComponent gic = getGuardedInvocationComponent( |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
363 |
new ComponentLinkRequest(request, linkerServices)); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
364 |
return gic != null ? gic.getGuardedInvocation() : null; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
365 |
} |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
366 |
|
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
367 |
static final class ComponentLinkRequest { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
368 |
final LinkRequest linkRequest; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
369 |
final LinkerServices linkerServices; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
370 |
final List<Operation> operations; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
371 |
final Object name; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
372 |
|
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
373 |
ComponentLinkRequest(final LinkRequest linkRequest, |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
374 |
final LinkerServices linkerServices) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
375 |
this.linkRequest = linkRequest; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
376 |
this.linkerServices = linkerServices; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
377 |
final Operation operation = linkRequest.getCallSiteDescriptor().getOperation(); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
378 |
this.operations = Arrays.asList( |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
379 |
CompositeOperation.getOperations( |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
380 |
NamedOperation.getBaseOperation(operation))); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
381 |
this.name = NamedOperation.getName(operation); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
382 |
} |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
383 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
384 |
private ComponentLinkRequest(final LinkRequest linkRequest, |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
385 |
final LinkerServices linkerServices, |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
386 |
final List<Operation> operations, final Object name) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
387 |
this.linkRequest = linkRequest; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
388 |
this.linkerServices = linkerServices; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
389 |
this.operations = operations; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
390 |
this.name = name; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
391 |
} |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
392 |
|
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
393 |
CallSiteDescriptor getDescriptor() { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
394 |
return linkRequest.getCallSiteDescriptor(); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
395 |
} |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
396 |
|
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
397 |
ComponentLinkRequest popOperations() { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
398 |
return new ComponentLinkRequest(linkRequest, linkerServices, |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
399 |
operations.subList(1, operations.size()), name); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
400 |
} |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
401 |
} |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
402 |
|
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
403 |
protected GuardedInvocationComponent getGuardedInvocationComponent(final ComponentLinkRequest req) |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
404 |
throws Exception { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
405 |
final Operation op = req.operations.get(0); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
406 |
if (op instanceof StandardOperation) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
407 |
switch((StandardOperation)op) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
408 |
case GET_PROPERTY: return getPropertyGetter(req.popOperations()); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
409 |
case SET_PROPERTY: return getPropertySetter(req.popOperations()); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
410 |
case GET_METHOD: return getMethodGetter(req.popOperations()); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
411 |
default: |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
412 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
413 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
414 |
return null; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
415 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
416 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
417 |
GuardedInvocationComponent getNextComponent(final ComponentLinkRequest req) throws Exception { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
418 |
if (req.operations.isEmpty()) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
419 |
return null; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
420 |
} |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
421 |
final GuardedInvocationComponent gic = getGuardedInvocationComponent(req); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
422 |
if (gic != null) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
423 |
return gic; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
424 |
} |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
425 |
return getNextComponent(req.popOperations()); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
426 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
427 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
428 |
static final <T> List<T> pop(final List<T> l) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
429 |
return l.subList(1, l.size()); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
430 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
431 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
432 |
MethodHandle getClassGuard(final CallSiteDescriptor desc) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
433 |
return getClassGuard(desc.getMethodType()); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
434 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
435 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
436 |
MethodHandle getClassGuard(final MethodType type) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
437 |
return Guards.asType(classGuard, type); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
438 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
439 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
440 |
GuardedInvocationComponent getClassGuardedInvocationComponent(final MethodHandle invocation, final MethodType type) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
441 |
return new GuardedInvocationComponent(invocation, getClassGuard(type), clazz, ValidationType.EXACT_CLASS); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
442 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
443 |
|
33688 | 444 |
abstract SingleDynamicMethod getConstructorMethod(final String signature); |
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
445 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
446 |
private MethodHandle getAssignableGuard(final MethodType type) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
447 |
return Guards.asType(assignableGuard, type); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
448 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
449 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
450 |
private GuardedInvocation createGuardedDynamicMethodInvocation(final CallSiteDescriptor callSiteDescriptor, |
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
451 |
final LinkerServices linkerServices, final String methodName, final Map<String, DynamicMethod> methodMap){ |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
452 |
final MethodHandle inv = getDynamicMethodInvocation(callSiteDescriptor, linkerServices, methodName, methodMap); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
453 |
return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteDescriptor.getMethodType())); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
454 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
455 |
|
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
456 |
private MethodHandle getDynamicMethodInvocation(final CallSiteDescriptor callSiteDescriptor, |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
457 |
final LinkerServices linkerServices, final String methodName, final Map<String, DynamicMethod> methodMap) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
458 |
final DynamicMethod dynaMethod = getDynamicMethod(methodName, methodMap); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
459 |
return dynaMethod != null ? dynaMethod.getInvocation(callSiteDescriptor, linkerServices) : null; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
460 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
461 |
|
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
462 |
private DynamicMethod getDynamicMethod(final String methodName, final Map<String, DynamicMethod> methodMap) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
463 |
final DynamicMethod dynaMethod = methodMap.get(methodName); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
464 |
return dynaMethod != null ? dynaMethod : getExplicitSignatureDynamicMethod(methodName, methodMap); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
465 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
466 |
|
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
467 |
private SingleDynamicMethod getExplicitSignatureDynamicMethod(final String fullName, |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
468 |
final Map<String, DynamicMethod> methodsMap) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
469 |
// What's below is meant to support the "name(type, type, ...)" syntax that programmers can use in a method name |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
470 |
// to manually pin down an exact overloaded variant. This is not usually required, as the overloaded method |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
471 |
// resolution works correctly in almost every situation. However, in presence of many language-specific |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
472 |
// conversions with a radically dynamic language, most overloaded methods will end up being constantly selected |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
473 |
// at invocation time, so a programmer knowledgeable of the situation might choose to pin down an exact overload |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
474 |
// for performance reasons. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
475 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
476 |
// Is the method name lexically of the form "name(types)"? |
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
477 |
final int lastChar = fullName.length() - 1; |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
478 |
if(fullName.charAt(lastChar) != ')') { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
479 |
return null; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
480 |
} |
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
481 |
final int openBrace = fullName.indexOf('('); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
482 |
if(openBrace == -1) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
483 |
return null; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
484 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
485 |
|
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
486 |
final String name = fullName.substring(0, openBrace); |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
487 |
final String signature = fullName.substring(openBrace + 1, lastChar); |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
488 |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
489 |
// Find an existing method for the "name" part |
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
490 |
final DynamicMethod simpleNamedMethod = methodsMap.get(name); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
491 |
if(simpleNamedMethod == null) { |
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
492 |
// explicit signature constructor access |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
493 |
// Java.type("java.awt.Color")["(int,int,int)"] |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
494 |
// will get Color(int,int,int) constructor of Color class. |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
495 |
if (name.isEmpty()) { |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
496 |
return getConstructorMethod(signature); |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
497 |
} |
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
498 |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
499 |
return null; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
500 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
501 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
502 |
// Try to get a narrowed dynamic method for the explicit parameter types. |
25258
325380d7c38c
8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents:
25252
diff
changeset
|
503 |
return simpleNamedMethod.getMethodForExactParamTypes(signature); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
504 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
505 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
506 |
private static final MethodHandle IS_METHOD_HANDLE_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType( |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
507 |
boolean.class, MethodHandle.class)); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
508 |
private static final MethodHandle CONSTANT_NULL_DROP_METHOD_HANDLE = MethodHandles.dropArguments( |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
509 |
MethodHandles.constant(Object.class, null), 0, MethodHandle.class); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
510 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
511 |
private GuardedInvocationComponent getPropertySetter(final ComponentLinkRequest req) throws Exception { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
512 |
if (req.name == null) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
513 |
return getUnnamedPropertySetter(req); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
514 |
} |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
515 |
return getNamedPropertySetter(req); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
516 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
517 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
518 |
private GuardedInvocationComponent getUnnamedPropertySetter(final ComponentLinkRequest req) throws Exception { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
519 |
final CallSiteDescriptor callSiteDescriptor = req.getDescriptor(); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
520 |
// Must have three arguments: target object, property name, and property value. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
521 |
assertParameterCount(callSiteDescriptor, 3); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
522 |
|
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
523 |
// We want setters that conform to "Object(O, V)". Note, we aren't doing "R(O, V)" as it might not be |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
524 |
// valid for us to convert return values proactively. Also, since we don't know what setters will be |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
525 |
// invoked, we'll conservatively presume Object return type. The one exception is void return. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
526 |
final MethodType origType = callSiteDescriptor.getMethodType(); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
527 |
final MethodType type = origType.returnType() == void.class ? origType : origType.changeReturnType(Object.class); |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
528 |
final LinkerServices linkerServices = req.linkerServices; |
24719 | 529 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
530 |
// What's below is basically: |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
531 |
// foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation), |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
532 |
// get_setter_handle(type, linkerServices)) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
533 |
// only with a bunch of method signature adjustments. Basically, retrieve method setter |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
534 |
// MethodHandle; if it is non-null, invoke it, otherwise either return null, or delegate to next |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
535 |
// component's invocation. |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
536 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
537 |
// Call site type is "ret_type(object_type,property_name_type,property_value_type)", which we'll |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
538 |
// abbreviate to R(O, N, V) going forward, although we don't really use R here (see above about using |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
539 |
// Object return type). |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
540 |
final MethodType setterType = type.dropParameterTypes(1, 2); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
541 |
// Bind property setter handle to the expected setter type and linker services. Type is |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
542 |
// MethodHandle(Object, String, Object) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
543 |
final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
544 |
callSiteDescriptor.changeMethodType(setterType), linkerServices); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
545 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
546 |
// Cast getter to MethodHandle(O, N, V) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
547 |
final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType( |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
548 |
MethodHandle.class)); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
549 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
550 |
// Handle to invoke the setter R(MethodHandle, O, V) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
551 |
final MethodHandle invokeHandle = MethodHandles.exactInvoker(setterType); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
552 |
// Handle to invoke the setter, dropping unnecessary fold arguments R(MethodHandle, O, N, V) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
553 |
final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandle, 2, type.parameterType( |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
554 |
1)); |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
555 |
final GuardedInvocationComponent nextComponent = getNextComponent(req); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
556 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
557 |
final MethodHandle fallbackFolded; |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
558 |
if (nextComponent == null) { |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
559 |
// Object(MethodHandle)->Object(MethodHandle, O, N, V); returns constant null |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
560 |
fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_METHOD_HANDLE, 1, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
561 |
type.parameterList()).asType(type.insertParameterTypes(0, MethodHandle.class)); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
562 |
} else { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
563 |
// Object(O, N, V)->Object(MethodHandle, O, N, V); adapts the next component's invocation to drop the |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
564 |
// extra argument resulting from fold |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
565 |
fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(), |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
566 |
0, MethodHandle.class); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
567 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
568 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
569 |
// fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V)) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
570 |
final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest( |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
571 |
IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
572 |
if(nextComponent == null) { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
573 |
return getClassGuardedInvocationComponent(compositeSetter, type); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
574 |
} |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
575 |
return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
576 |
} |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
577 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
578 |
private GuardedInvocationComponent getNamedPropertySetter(final ComponentLinkRequest req) throws Exception { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
579 |
final CallSiteDescriptor callSiteDescriptor = req.getDescriptor(); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
580 |
// Must have two arguments: target object and property value |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
581 |
assertParameterCount(callSiteDescriptor, 2); |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
582 |
final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, req.linkerServices, |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
583 |
req.name.toString(), propertySetters); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
584 |
// If we have a property setter with this name, this composite operation will always stop here |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
585 |
if(gi != null) { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
586 |
return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
587 |
} |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
588 |
// If we don't have a property setter with this name, always fall back to the next operation in the |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
589 |
// composite (if any) |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
590 |
return getNextComponent(req); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
591 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
592 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
593 |
private static final Lookup privateLookup = new Lookup(MethodHandles.lookup()); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
594 |
|
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
595 |
private static final MethodHandle IS_ANNOTATED_METHOD_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType( |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
596 |
boolean.class, AnnotatedDynamicMethod.class)); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
597 |
private static final MethodHandle CONSTANT_NULL_DROP_ANNOTATED_METHOD = MethodHandles.dropArguments( |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
598 |
MethodHandles.constant(Object.class, null), 0, AnnotatedDynamicMethod.class); |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
599 |
private static final MethodHandle GET_ANNOTATED_METHOD = privateLookup.findVirtual(AnnotatedDynamicMethod.class, |
33331
273e6a10de22
8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents:
33330
diff
changeset
|
600 |
"getTarget", MethodType.methodType(MethodHandle.class, CallSiteDescriptor.class, LinkerServices.class)); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
601 |
private static final MethodHandle GETTER_INVOKER = MethodHandles.invoker(MethodType.methodType(Object.class, Object.class)); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
602 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
603 |
private GuardedInvocationComponent getPropertyGetter(final ComponentLinkRequest req) throws Exception { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
604 |
if (req.name == null) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
605 |
return getUnnamedPropertyGetter(req); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
606 |
} |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
607 |
return getNamedPropertyGetter(req); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
608 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
609 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
610 |
private GuardedInvocationComponent getUnnamedPropertyGetter(final ComponentLinkRequest req) throws Exception { |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
611 |
// Since we can't know what kind of a getter we'll get back on different invocations, we'll just |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
612 |
// conservatively presume Object. Note we can't just coerce to a narrower call site type as the linking |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
613 |
// runtime might not allow coercing at that call site. |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
614 |
final CallSiteDescriptor callSiteDescriptor = req.getDescriptor(); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
615 |
final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
616 |
// Must have exactly two arguments: receiver and name |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
617 |
assertParameterCount(callSiteDescriptor, 2); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
618 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
619 |
// What's below is basically: |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
620 |
// foldArguments(guardWithTest(isNotNull, invoke(get_handle), null|nextComponent.invocation), get_getter_handle) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
621 |
// only with a bunch of method signature adjustments. Basically, retrieve method getter |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
622 |
// AnnotatedDynamicMethod; if it is non-null, invoke its "handle" field, otherwise either return null, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
623 |
// or delegate to next component's invocation. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
624 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
625 |
final LinkerServices linkerServices = req.linkerServices; |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
626 |
final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType( |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
627 |
AnnotatedDynamicMethod.class)); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
628 |
final MethodHandle callSiteBoundMethodGetter = MethodHandles.insertArguments( |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
629 |
GET_ANNOTATED_METHOD, 1, callSiteDescriptor, linkerServices); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
630 |
final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
631 |
callSiteBoundMethodGetter); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
632 |
// Object(AnnotatedDynamicMethod, Object)->Object(AnnotatedDynamicMethod, T0) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
633 |
final MethodHandle invokeHandleTyped = linkerServices.asType(callSiteBoundInvoker, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
634 |
MethodType.methodType(type.returnType(), AnnotatedDynamicMethod.class, type.parameterType(0))); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
635 |
// Since it's in the target of a fold, drop the unnecessary second argument |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
636 |
// Object(AnnotatedDynamicMethod, T0)->Object(AnnotatedDynamicMethod, T0, T1) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
637 |
final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
638 |
type.parameterType(1)); |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
639 |
final GuardedInvocationComponent nextComponent = getNextComponent(req); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
640 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
641 |
final MethodHandle fallbackFolded; |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
642 |
if(nextComponent == null) { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
643 |
// Object(AnnotatedDynamicMethod)->Object(AnnotatedDynamicMethod, T0, T1); returns constant null |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
644 |
fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_METHOD, 1, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
645 |
type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedDynamicMethod.class)); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
646 |
} else { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
647 |
// Object(T0, T1)->Object(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
648 |
// drop the extra argument resulting from fold and to change its return type to Object. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
649 |
final MethodHandle nextInvocation = nextComponent.getGuardedInvocation().getInvocation(); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
650 |
final MethodType nextType = nextInvocation.type(); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
651 |
fallbackFolded = MethodHandles.dropArguments(nextInvocation.asType( |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
652 |
nextType.changeReturnType(Object.class)), 0, AnnotatedDynamicMethod.class); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
653 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
654 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
655 |
// fold(Object(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1)) |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
656 |
final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest( |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
657 |
IS_ANNOTATED_METHOD_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
658 |
if(nextComponent == null) { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
659 |
return getClassGuardedInvocationComponent(compositeGetter, type); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
660 |
} |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
661 |
return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
662 |
} |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
663 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
664 |
private GuardedInvocationComponent getNamedPropertyGetter(final ComponentLinkRequest req) throws Exception { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
665 |
final CallSiteDescriptor callSiteDescriptor = req.getDescriptor(); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
666 |
// Must have exactly one argument: receiver |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
667 |
assertParameterCount(callSiteDescriptor, 1); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
668 |
// Fixed name |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
669 |
final AnnotatedDynamicMethod annGetter = propertyGetters.get(req.name.toString()); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
670 |
if(annGetter == null) { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
671 |
// We have no such property, always delegate to the next component operation |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
672 |
return getNextComponent(req); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
673 |
} |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
674 |
final MethodHandle getter = annGetter.getInvocation(req); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
675 |
// NOTE: since property getters (not field getters!) are no-arg, we don't have to worry about them being |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
676 |
// overloaded in a subclass. Therefore, we can discover the most abstract superclass that has the |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
677 |
// method, and use that as the guard with Guards.isInstance() for a more stably linked call site. If |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
678 |
// we're linking against a field getter, don't make the assumption. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
679 |
// NOTE: No delegation to the next component operation if we have a property with this name, even if its |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
680 |
// value is null. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
681 |
final ValidationType validationType = annGetter.validationType; |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
682 |
// TODO: we aren't using the type that declares the most generic getter here! |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
683 |
return new GuardedInvocationComponent(getter, getGuard(validationType, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
684 |
callSiteDescriptor.getMethodType()), clazz, validationType); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
685 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
686 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
687 |
private MethodHandle getGuard(final ValidationType validationType, final MethodType methodType) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
688 |
switch(validationType) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
689 |
case EXACT_CLASS: { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
690 |
return getClassGuard(methodType); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
691 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
692 |
case INSTANCE_OF: { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
693 |
return getAssignableGuard(methodType); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
694 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
695 |
case IS_ARRAY: { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
696 |
return Guards.isArray(0, methodType); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
697 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
698 |
case NONE: { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
699 |
return null; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
700 |
} |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
701 |
default: { |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
702 |
throw new AssertionError(); |
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
703 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
704 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
705 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
706 |
|
24719 | 707 |
private static final MethodHandle IS_DYNAMIC_METHOD = Guards.isInstance(DynamicMethod.class, |
708 |
MethodType.methodType(boolean.class, Object.class)); |
|
709 |
private static final MethodHandle OBJECT_IDENTITY = MethodHandles.identity(Object.class); |
|
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
710 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
711 |
private GuardedInvocationComponent getMethodGetter(final ComponentLinkRequest req) throws Exception { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
712 |
if (req.name == null) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
713 |
return getUnnamedMethodGetter(req); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
714 |
} |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
715 |
return getNamedMethodGetter(req); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
716 |
} |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
717 |
|
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
718 |
private static MethodType getMethodGetterType(final ComponentLinkRequest req) { |
24719 | 719 |
// The created method handle will always return a DynamicMethod (or null), but since we don't want that type to |
720 |
// be visible outside of this linker, declare it to return Object. |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
721 |
return req.getDescriptor().getMethodType().changeReturnType(Object.class); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
722 |
} |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
723 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
724 |
private GuardedInvocationComponent getUnnamedMethodGetter(final ComponentLinkRequest req) throws Exception { |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
725 |
// Must have exactly two arguments: receiver and name |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
726 |
assertParameterCount(req.getDescriptor(), 2); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
727 |
final GuardedInvocationComponent nextComponent = getNextComponent(req); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
728 |
final LinkerServices linkerServices = req.linkerServices; |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
729 |
final MethodType type = getMethodGetterType(req); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
730 |
if(nextComponent == null) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
731 |
// No next component operation; just return a component for this operation. |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
732 |
return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
733 |
} |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
734 |
|
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
735 |
// What's below is basically: |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
736 |
// foldArguments(guardWithTest(isNotNull, identity, nextComponent.invocation), getter) only with a |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
737 |
// bunch of method signature adjustments. Basically, execute method getter; if it returns a non-null |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
738 |
// DynamicMethod, use identity to return it, otherwise delegate to nextComponent's invocation. |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
739 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
740 |
final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
741 |
// Since it is part of the foldArgument() target, it will have extra args that we need to drop. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
742 |
final MethodHandle returnMethodHandle = linkerServices.asType(MethodHandles.dropArguments( |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
743 |
OBJECT_IDENTITY, 1, type.parameterList()), type.insertParameterTypes(0, Object.class)); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
744 |
final MethodHandle nextComponentInvocation = nextComponent.getGuardedInvocation().getInvocation(); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
745 |
// The assumption is that getGuardedInvocationComponent() already asType()'d it correctly modulo the |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
746 |
// return type. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
747 |
assert nextComponentInvocation.type().changeReturnType(type.returnType()).equals(type); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
748 |
// Since it is part of the foldArgument() target, we have to drop an extra arg it receives. |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
749 |
final MethodHandle nextCombinedInvocation = MethodHandles.dropArguments(nextComponentInvocation, 0, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
750 |
Object.class); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
751 |
// Assemble it all into a fold(guard(isNotNull, identity, nextInvocation), get) |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
752 |
// Note that nextCombinedInvocation needs to have its return type changed to Object |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
753 |
final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest( |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
754 |
IS_DYNAMIC_METHOD, returnMethodHandle, |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
755 |
nextCombinedInvocation.asType(nextCombinedInvocation.type().changeReturnType(Object.class))), |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
756 |
typedGetter); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
757 |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
758 |
return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS); |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
759 |
} |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
760 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
761 |
private GuardedInvocationComponent getNamedMethodGetter(final ComponentLinkRequest req) |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
762 |
throws Exception { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
763 |
// Must have exactly one argument: receiver |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
764 |
assertParameterCount(req.getDescriptor(), 1); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
765 |
final DynamicMethod method = getDynamicMethod(req.name.toString()); |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
766 |
if(method == null) { |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
767 |
// We have no such method, always delegate to the next component |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
768 |
return getNextComponent(req); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
769 |
} |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
770 |
// No delegation to the next component of the composite operation; if we have a method with that name, |
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
771 |
// we'll always return it at this point. |
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
772 |
final MethodType type = getMethodGetterType(req); |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
773 |
return getClassGuardedInvocationComponent(req.linkerServices.asType(MethodHandles.dropArguments( |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
774 |
MethodHandles.constant(Object.class, method), 0, type.parameterType(0)), type), type); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
775 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
776 |
|
24719 | 777 |
static class MethodPair { |
778 |
final MethodHandle method1; |
|
779 |
final MethodHandle method2; |
|
780 |
||
781 |
MethodPair(final MethodHandle method1, final MethodHandle method2) { |
|
782 |
this.method1 = method1; |
|
783 |
this.method2 = method2; |
|
784 |
} |
|
785 |
||
786 |
MethodHandle guardWithTest(final MethodHandle test) { |
|
787 |
return MethodHandles.guardWithTest(test, method1, method2); |
|
788 |
} |
|
789 |
} |
|
790 |
||
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
791 |
static MethodPair matchReturnTypes(final MethodHandle m1, final MethodHandle m2) { |
24719 | 792 |
final MethodType type1 = m1.type(); |
793 |
final MethodType type2 = m2.type(); |
|
33338
faf6471e1cc8
8139887: Reduce visibility of few methods in TypeUtilities and Guards API
attila
parents:
33337
diff
changeset
|
794 |
final Class<?> commonRetType = InternalTypeUtilities.getCommonLosslessConversionType(type1.returnType(), |
24719 | 795 |
type2.returnType()); |
796 |
return new MethodPair( |
|
797 |
m1.asType(type1.changeReturnType(commonRetType)), |
|
798 |
m2.asType(type2.changeReturnType(commonRetType))); |
|
799 |
} |
|
800 |
||
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
801 |
private static void assertParameterCount(final CallSiteDescriptor descriptor, final int paramCount) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
802 |
if(descriptor.getMethodType().parameterCount() != paramCount) { |
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
803 |
throw new BootstrapMethodError(descriptor.getOperation() + " must have exactly " + paramCount + " parameters."); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
804 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
805 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
806 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
807 |
private static MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial( |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
808 |
"getPropertyGetterHandle", Object.class, Object.class), 1, Object.class); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
809 |
private final MethodHandle getPropertyGetterHandle = GET_PROPERTY_GETTER_HANDLE.bindTo(this); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
810 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
811 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
812 |
* @param id the property ID |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
813 |
* @return the method handle for retrieving the property, or null if the property does not exist |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
814 |
*/ |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
815 |
@SuppressWarnings("unused") |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
816 |
private Object getPropertyGetterHandle(final Object id) { |
34842
c8054093d6e7
8146147: Java linker indexed property getter does not work for computed nashorn string
sundar
parents:
34447
diff
changeset
|
817 |
return propertyGetters.get(String.valueOf(id)); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
818 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
819 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
820 |
// Type is MethodHandle(BeanLinker, MethodType, LinkerServices, Object, String, Object), of which the two "Object" |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
821 |
// args are dropped; this makes handles with first three args conform to "Object, String, Object" though, which is |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
822 |
// a typical property setter with variable name signature (target, name, value). |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
823 |
private static final MethodHandle GET_PROPERTY_SETTER_HANDLE = MethodHandles.dropArguments(MethodHandles.dropArguments( |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
824 |
privateLookup.findOwnSpecial("getPropertySetterHandle", MethodHandle.class, CallSiteDescriptor.class, |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
825 |
LinkerServices.class, Object.class), 3, Object.class), 5, Object.class); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
826 |
// Type is MethodHandle(MethodType, LinkerServices, Object, String, Object) |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
827 |
private final MethodHandle getPropertySetterHandle = GET_PROPERTY_SETTER_HANDLE.bindTo(this); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
828 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
829 |
@SuppressWarnings("unused") |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
830 |
private MethodHandle getPropertySetterHandle(final CallSiteDescriptor setterDescriptor, final LinkerServices linkerServices, |
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
831 |
final Object id) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
832 |
return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
833 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
834 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
835 |
private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial( |
24719 | 836 |
"getDynamicMethod", Object.class, Object.class), 1, Object.class); |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
837 |
private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
838 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
839 |
@SuppressWarnings("unused") |
24719 | 840 |
// This method is marked to return Object instead of DynamicMethod as it's used as a linking component and we don't |
841 |
// want to make the DynamicMethod type observable externally (e.g. as the return type of a MethodHandle returned for |
|
33343
23abd10384a5
8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents:
33338
diff
changeset
|
842 |
// GET_METHOD linking). |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
843 |
private Object getDynamicMethod(final Object name) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
844 |
return getDynamicMethod(String.valueOf(name), methods); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
845 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
846 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
847 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
848 |
* Returns a dynamic method of the specified name. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
849 |
* |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
850 |
* @param name name of the method |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
851 |
* @return the dynamic method (either {@link SimpleDynamicMethod} or {@link OverloadedDynamicMethod}, or null if the |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
852 |
* method with the specified name does not exist. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
853 |
*/ |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
854 |
DynamicMethod getDynamicMethod(final String name) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
855 |
return getDynamicMethod(name, methods); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
856 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
857 |
|
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
858 |
/** |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
859 |
* Find the most generic superclass that declares this getter. Since getters have zero args (aside from the |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
860 |
* receiver), they can't be overloaded, so we're free to link with an instanceof guard for the most generic one, |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
861 |
* creating more stable call sites. |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
862 |
* @param getter the getter |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
863 |
* @return getter with same name, declared on the most generic superclass/interface of the declaring class |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
864 |
*/ |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
865 |
private static Method getMostGenericGetter(final Method getter) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
866 |
return getMostGenericGetter(getter.getName(), getter.getReturnType(), getter.getDeclaringClass()); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
867 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
868 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
869 |
private static Method getMostGenericGetter(final String name, final Class<?> returnType, final Class<?> declaringClass) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
870 |
if(declaringClass == null) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
871 |
return null; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
872 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
873 |
// Prefer interfaces |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
874 |
for(final Class<?> itf: declaringClass.getInterfaces()) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
875 |
final Method itfGetter = getMostGenericGetter(name, returnType, itf); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
876 |
if(itfGetter != null) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
877 |
return itfGetter; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
878 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
879 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
880 |
final Method superGetter = getMostGenericGetter(name, returnType, declaringClass.getSuperclass()); |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
881 |
if(superGetter != null) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
882 |
return superGetter; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
883 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
884 |
if(!CheckRestrictedPackage.isRestrictedClass(declaringClass)) { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
885 |
try { |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
886 |
return declaringClass.getMethod(name); |
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
887 |
} catch(final NoSuchMethodException e) { |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
888 |
// Intentionally ignored, meant to fall through |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
889 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
890 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
891 |
return null; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
892 |
} |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
893 |
|
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
894 |
private static final class AnnotatedDynamicMethod { |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
895 |
private final SingleDynamicMethod method; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
896 |
/*private*/ final ValidationType validationType; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
897 |
|
24778
2ff5d7041566
8044638: Tidy up Nashorn codebase for code standards
attila
parents:
24719
diff
changeset
|
898 |
AnnotatedDynamicMethod(final SingleDynamicMethod method, final ValidationType validationType) { |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
899 |
this.method = method; |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
900 |
this.validationType = validationType; |
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
901 |
} |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
902 |
|
34978
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
903 |
MethodHandle getInvocation(final ComponentLinkRequest req) { |
e753c4c9f96f
8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents:
34842
diff
changeset
|
904 |
return method.getInvocation(req.getDescriptor(), req.linkerServices); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
905 |
} |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
906 |
|
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
907 |
@SuppressWarnings("unused") |
33331
273e6a10de22
8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents:
33330
diff
changeset
|
908 |
MethodHandle getTarget(final CallSiteDescriptor desc, final LinkerServices linkerServices) { |
273e6a10de22
8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents:
33330
diff
changeset
|
909 |
final MethodHandle inv = linkerServices.filterInternalObjects(method.getTarget(desc)); |
18841
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
910 |
assert inv != null; |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
911 |
return inv; |
9bbc4b8832b2
8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents:
16267
diff
changeset
|
912 |
} |
16234
86cb162cec6c
8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff
changeset
|
913 |
} |
16245
6a1c6c8bc113
8008371: Fix Dynalink compiler warnings and whitespace
attila
parents:
16234
diff
changeset
|
914 |
} |