src/jdk.dynalink/share/classes/jdk/dynalink/beans/AbstractJavaLinker.java
author attila
Wed, 20 Dec 2017 17:36:50 +0100
changeset 48411 4ff5c5206427
parent 47216 71c04702a3d5
child 50695 36ca515343e0
permissions -rw-r--r--
8193371: Use Dynalink REMOVE operation in Nashorn Reviewed-by: hannesw, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
649d5d76f602 8142422: Smaller Dynalink API adjustments
attila
parents: 33343
diff changeset
   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.NamedOperation;
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   103
import jdk.dynalink.Namespace;
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   104
import jdk.dynalink.NamespaceOperation;
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   105
import jdk.dynalink.Operation;
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   106
import jdk.dynalink.StandardNamespace;
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   107
import jdk.dynalink.StandardOperation;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   108
import jdk.dynalink.beans.GuardedInvocationComponent.ValidationType;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   109
import jdk.dynalink.internal.InternalTypeUtilities;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   110
import jdk.dynalink.linker.GuardedInvocation;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   111
import jdk.dynalink.linker.GuardingDynamicLinker;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   112
import jdk.dynalink.linker.LinkRequest;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   113
import jdk.dynalink.linker.LinkerServices;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   114
import jdk.dynalink.linker.support.Guards;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33688
diff changeset
   115
import jdk.dynalink.linker.support.Lookup;
37379
e9c85d2b1fcc 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 34979
diff changeset
   116
import jdk.internal.reflect.CallerSensitive;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   117
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   118
/**
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   119
 * 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
   120
 * 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
   121
 */
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   122
abstract class AbstractJavaLinker implements GuardingDynamicLinker {
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   123
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   124
    final Class<?> clazz;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   125
    private final MethodHandle classGuard;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   126
    private final MethodHandle assignableGuard;
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   127
    private final Map<String, AnnotatedDynamicMethod> propertyGetters = new HashMap<>();
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   128
    private final Map<String, DynamicMethod> propertySetters = new HashMap<>();
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   129
    private final Map<String, DynamicMethod> methods = new HashMap<>();
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   130
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   131
    AbstractJavaLinker(final Class<?> clazz, final MethodHandle classGuard) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   132
        this(clazz, classGuard, classGuard);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   133
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   134
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   135
    AbstractJavaLinker(final Class<?> clazz, final MethodHandle classGuard, final MethodHandle assignableGuard) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   136
        this.clazz = clazz;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   137
        this.classGuard = classGuard;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   138
        this.assignableGuard = assignableGuard;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   139
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   140
        final FacetIntrospector introspector = createFacetIntrospector();
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   141
        // Add methods and properties
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   142
        for(final Method method: introspector.getMethods()) {
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   143
            final String name = method.getName();
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   144
            // Add method
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   145
            addMember(name, method, methods);
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   146
            // Add the method as a property getter and/or setter
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   147
            if(name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0) {
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   148
                // Property getter
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   149
                setPropertyGetter(method, 3);
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   150
            } 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
   151
                    method.getReturnType() == boolean.class) {
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   152
                // Boolean property getter
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   153
                setPropertyGetter(method, 2);
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   154
            } 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
   155
                // Property setter
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   156
                addMember(decapitalize(name.substring(3)), method, propertySetters);
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
        }
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   159
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   160
        // Add field getter/setters as property getters/setters.
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   161
        for(final Field field: introspector.getFields()) {
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   162
            final String name = field.getName();
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   163
            // 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
   164
            if(!propertyGetters.containsKey(name)) {
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   165
                setPropertyGetter(name, introspector.unreflectGetter(field), ValidationType.EXACT_CLASS);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   166
            }
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   167
            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
   168
                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
   169
                        propertySetters);
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   170
            }
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   171
        }
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   172
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   173
        // 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
   174
        for(final Map.Entry<String, MethodHandle> innerClassSpec: introspector.getInnerClassGetters().entrySet()) {
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   175
            final String name = innerClassSpec.getKey();
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   176
            if(!propertyGetters.containsKey(name)) {
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   177
                setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS);
16234
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
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   180
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   181
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   182
    private static String decapitalize(final String str) {
16267
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   183
        assert str != null;
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   184
        if(str.isEmpty()) {
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   185
            return str;
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   186
        }
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   187
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   188
        final char c0 = str.charAt(0);
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   189
        if(Character.isLowerCase(c0)) {
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   190
            return str;
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   191
        }
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   192
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   193
        // 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
   194
        if(str.length() > 1 && Character.isUpperCase(str.charAt(1))) {
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   195
            return str;
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   196
        }
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   197
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   198
        final char c[] = str.toCharArray();
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   199
        c[0] = Character.toLowerCase(c0);
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   200
        return new String(c);
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   201
    }
cd471d62bb6a 8009143: Eliminate Dynalink dependency on java.beans
attila
parents: 16245
diff changeset
   202
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   203
    abstract FacetIntrospector createFacetIntrospector();
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   204
33688
649d5d76f602 8142422: Smaller Dynalink API adjustments
attila
parents: 33343
diff changeset
   205
    Set<String> getReadablePropertyNames() {
18876
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   206
        return getUnmodifiableKeys(propertyGetters);
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   207
    }
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   208
33688
649d5d76f602 8142422: Smaller Dynalink API adjustments
attila
parents: 33343
diff changeset
   209
    Set<String> getWritablePropertyNames() {
18876
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   210
        return getUnmodifiableKeys(propertySetters);
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   211
    }
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   212
33688
649d5d76f602 8142422: Smaller Dynalink API adjustments
attila
parents: 33343
diff changeset
   213
    Set<String> getMethodNames() {
18876
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   214
        return getUnmodifiableKeys(methods);
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   215
    }
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   216
33688
649d5d76f602 8142422: Smaller Dynalink API adjustments
attila
parents: 33343
diff changeset
   217
    private static Set<String> getUnmodifiableKeys(final Map<String, ?> m) {
649d5d76f602 8142422: Smaller Dynalink API adjustments
attila
parents: 33343
diff changeset
   218
        return Collections.unmodifiableSet(m.keySet());
18876
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   219
    }
ada98218aaae 8020324: Implement Object.bindProperties(target, source) for beans
attila
parents: 18841
diff changeset
   220
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   221
    /**
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   222
     * 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
   223
     * 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
   224
     * 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
   225
     * instead.
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   226
     * @param name name of the property
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   227
     * @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
   228
     * @param validationType the validation type for the property
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   229
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   230
    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
   231
        propertyGetters.put(name, new AnnotatedDynamicMethod(handle, validationType));
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   232
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   233
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   234
    /**
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   235
     * 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
   236
     * @param getter the getter method
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   237
     * @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
   238
     * names starting with "is".
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   239
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   240
    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
   241
        setPropertyGetter(decapitalize(getter.getName().substring(prefixLen)), createDynamicMethod(
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   242
                getMostGenericGetter(getter)), ValidationType.INSTANCE_OF);
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
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   245
    /**
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   246
     * 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
   247
     * 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
   248
     * 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
   249
     * instead.
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   250
     * @param name name of the property
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   251
     * @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
   252
     * @param validationType the validation type for the property
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   253
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   254
    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
   255
        setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType);
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   256
    }
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   257
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   258
    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
   259
        addMember(name, createDynamicMethod(ao), methodMap);
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   260
    }
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   261
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   262
    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
   263
        final DynamicMethod existingMethod = methodMap.get(name);
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   264
        final DynamicMethod newMethod = mergeMethods(method, existingMethod, clazz, name);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   265
        if(newMethod != existingMethod) {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   266
            methodMap.put(name, newMethod);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   267
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   268
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   269
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   270
    /**
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   271
     * 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
   272
     * 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
   273
     * @param members the reflective members
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   274
     * @param clazz the class declaring the reflective members
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   275
     * @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
   276
     * @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
   277
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   278
    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
   279
        DynamicMethod dynMethod = null;
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   280
        for(final AccessibleObject method: members) {
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   281
            dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name);
16234
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
        return dynMethod;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   284
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   285
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   286
    /**
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   287
     * 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
   288
     * 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
   289
     * dynamic method when needed.
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   290
     * @param m the reflective member
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   291
     * @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
   292
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   293
    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
   294
        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
   295
            // Method has @CallerSensitive annotation
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   296
            return new CallerSensitiveDynamicMethod(m);
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   297
        }
27359
59d61197a3f3 8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents: 25865
diff changeset
   298
        // 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
   299
        final MethodHandle mh;
59d61197a3f3 8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents: 25865
diff changeset
   300
        try {
59d61197a3f3 8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents: 25865
diff changeset
   301
            mh = unreflectSafely(m);
59d61197a3f3 8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents: 25865
diff changeset
   302
        } 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
   303
            // 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
   304
            // 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
   305
            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
   306
        }
59d61197a3f3 8062050: A method is considered caller sensitive, but it doesn't have the CallerSensitive annotation
attila
parents: 25865
diff changeset
   307
        // Proceed with non-caller sensitive
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   308
        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
   309
        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
   310
    }
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   311
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   312
    /**
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   313
     * 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
   314
     * 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
   315
     * 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
   316
     * unreflector as its caller, and thus completely useless.
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   317
     * @param m the method or constructor
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   318
     * @return the method handle
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   319
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   320
    private static MethodHandle unreflectSafely(final AccessibleObject m) {
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   321
        if(m instanceof Method) {
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   322
            final Method reflMethod = (Method)m;
19093
49bb7e75b326 8021189: Prevent access to constructors of restricted classes
attila
parents: 19092
diff changeset
   323
            final MethodHandle handle = Lookup.PUBLIC.unreflect(reflMethod);
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   324
            if(Modifier.isStatic(reflMethod.getModifiers())) {
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   325
                return StaticClassIntrospector.editStaticMethodHandle(handle);
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   326
            }
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   327
            return handle;
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   328
        }
19093
49bb7e75b326 8021189: Prevent access to constructors of restricted classes
attila
parents: 19092
diff changeset
   329
        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
   330
    }
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   331
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   332
    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
   333
        if(existing == null) {
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   334
            return method;
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   335
        } else if(existing.contains(method)) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   336
            return existing;
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   337
        } else if(existing instanceof SingleDynamicMethod) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   338
            final OverloadedDynamicMethod odm = new OverloadedDynamicMethod(clazz, name);
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   339
            odm.addMethod(((SingleDynamicMethod)existing));
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   340
            odm.addMethod(method);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   341
            return odm;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   342
        } else if(existing instanceof OverloadedDynamicMethod) {
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   343
            ((OverloadedDynamicMethod)existing).addMethod(method);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   344
            return existing;
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
        throw new AssertionError();
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   347
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   348
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   349
    @Override
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   350
    public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   351
            throws Exception {
33332
f180be6368d8 8139588: Remove concept of runtime context arguments, call site tokens, and link counts
attila
parents: 33331
diff changeset
   352
        final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor();
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   353
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   354
        final MissingMemberHandlerFactory missingMemberHandlerFactory;
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   355
        final LinkerServices directLinkerServices;
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   356
        if (linkerServices instanceof LinkerServicesWithMissingMemberHandlerFactory) {
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   357
            final LinkerServicesWithMissingMemberHandlerFactory lswmmhf = ((LinkerServicesWithMissingMemberHandlerFactory)linkerServices);
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   358
            missingMemberHandlerFactory = lswmmhf.missingMemberHandlerFactory;
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   359
            directLinkerServices = lswmmhf.linkerServices;
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   360
        } else {
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   361
            missingMemberHandlerFactory = null;
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   362
            directLinkerServices = linkerServices;
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   363
        }
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   364
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   365
        final GuardedInvocationComponent gic = getGuardedInvocationComponent(
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   366
                new ComponentLinkRequest(request, directLinkerServices,
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   367
                        missingMemberHandlerFactory));
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   368
        return gic != null ? gic.getGuardedInvocation() : null;
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   369
    }
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   370
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   371
    static final class ComponentLinkRequest {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   372
        final LinkRequest linkRequest;
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   373
        final LinkerServices linkerServices;
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   374
        final MissingMemberHandlerFactory missingMemberHandlerFactory;
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   375
        final Operation baseOperation;
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   376
        final List<Namespace> namespaces;
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   377
        final Object name;
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   378
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   379
        ComponentLinkRequest(final LinkRequest linkRequest,
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   380
                final LinkerServices linkerServices,
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   381
                final MissingMemberHandlerFactory missingMemberHandlerFactory) {
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   382
            this.linkRequest = linkRequest;
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   383
            this.linkerServices = linkerServices;
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   384
            this.missingMemberHandlerFactory = missingMemberHandlerFactory;
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   385
            final Operation namedOp = linkRequest.getCallSiteDescriptor().getOperation();
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   386
            this.name = NamedOperation.getName(namedOp);
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   387
            final Operation namespaceOp = NamedOperation.getBaseOperation(namedOp);
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   388
            this.baseOperation = NamespaceOperation.getBaseOperation(namespaceOp);
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   389
            this.namespaces = Arrays.asList(NamespaceOperation.getNamespaces(namespaceOp));
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   390
        }
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   391
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   392
        private ComponentLinkRequest(final LinkRequest linkRequest,
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   393
                final LinkerServices linkerServices,
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   394
                final MissingMemberHandlerFactory missingMemberHandlerFactory,
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   395
                final Operation baseOperation, final List<Namespace> namespaces, final Object name) {
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   396
            this.linkRequest = linkRequest;
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   397
            this.linkerServices = linkerServices;
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   398
            this.missingMemberHandlerFactory = missingMemberHandlerFactory;
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   399
            this.baseOperation = baseOperation;
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   400
            this.namespaces = namespaces;
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   401
            this.name = name;
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
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   404
        CallSiteDescriptor getDescriptor() {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   405
            return linkRequest.getCallSiteDescriptor();
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   406
        }
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   407
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   408
        ComponentLinkRequest popNamespace() {
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   409
            return new ComponentLinkRequest(linkRequest, linkerServices,
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   410
                    missingMemberHandlerFactory, baseOperation,
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   411
                namespaces.subList(1, namespaces.size()), name);
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   412
        }
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   413
    }
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   414
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   415
    protected GuardedInvocationComponent getGuardedInvocationComponent(final ComponentLinkRequest req)
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   416
    throws Exception {
48411
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   417
        if (req.namespaces.isEmpty()) {
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   418
            return null;
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   419
        }
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   420
        final Namespace ns = req.namespaces.get(0);
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   421
        final Operation op = req.baseOperation;
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   422
        if (op == StandardOperation.GET) {
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   423
            if (ns == StandardNamespace.PROPERTY) {
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   424
                return getPropertyGetter(req.popNamespace());
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   425
            } else if (ns == StandardNamespace.METHOD) {
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   426
                return getMethodGetter(req.popNamespace());
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   427
            }
48411
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   428
        } else if (op == StandardOperation.SET && ns == StandardNamespace.PROPERTY) {
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   429
            return getPropertySetter(req.popNamespace());
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   430
        }
48411
4ff5c5206427 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   431
        return getNextComponent(req.popNamespace());
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   432
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   433
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   434
    GuardedInvocationComponent getNextComponent(final ComponentLinkRequest req) throws Exception {
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   435
        if (req.namespaces.isEmpty()) {
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   436
            return createNoSuchMemberHandler(req.missingMemberHandlerFactory,
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   437
                    req.linkRequest, req.linkerServices);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   438
        }
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   439
        final GuardedInvocationComponent gic = getGuardedInvocationComponent(req);
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   440
        if (gic != null) {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   441
            return gic;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   442
        }
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   443
        return getNextComponent(req.popNamespace());
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   444
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   445
34979
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   446
    private GuardedInvocationComponent createNoSuchMemberHandler(
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   447
            final MissingMemberHandlerFactory missingMemberHandlerFactory,
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   448
            final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   449
        if (missingMemberHandlerFactory == null) {
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   450
            return null;
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   451
        }
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   452
        final MethodHandle handler = missingMemberHandlerFactory.createMissingMemberHandler(linkRequest, linkerServices);
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   453
        if (handler == null) {
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   454
            return null;
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   455
        }
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   456
        final MethodType type = linkRequest.getCallSiteDescriptor().getMethodType();
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   457
        // The returned handler is allowed to differ in return type.
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   458
        assert handler.type().changeReturnType(type.returnType()).equals(type);
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   459
        return getClassGuardedInvocationComponent(handler, type);
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   460
    }
03b189baa361 8144919: Implement missing member handler for BeansLinker
attila
parents: 34978
diff changeset
   461
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   462
    static final <T> List<T> pop(final List<T> l) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   463
        return l.subList(1, l.size());
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   464
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   465
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   466
    MethodHandle getClassGuard(final CallSiteDescriptor desc) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   467
        return getClassGuard(desc.getMethodType());
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   468
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   469
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   470
    MethodHandle getClassGuard(final MethodType type) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   471
        return Guards.asType(classGuard, type);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   472
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   473
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   474
    GuardedInvocationComponent getClassGuardedInvocationComponent(final MethodHandle invocation, final MethodType type) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   475
        return new GuardedInvocationComponent(invocation, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   476
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   477
33688
649d5d76f602 8142422: Smaller Dynalink API adjustments
attila
parents: 33343
diff changeset
   478
    abstract SingleDynamicMethod getConstructorMethod(final String signature);
25258
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   479
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   480
    private MethodHandle getAssignableGuard(final MethodType type) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   481
        return Guards.asType(assignableGuard, type);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   482
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   483
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   484
    private GuardedInvocation createGuardedDynamicMethodInvocation(final CallSiteDescriptor callSiteDescriptor,
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   485
            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
   486
        final MethodHandle inv = getDynamicMethodInvocation(callSiteDescriptor, linkerServices, methodName, methodMap);
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   487
        return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteDescriptor.getMethodType()));
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   488
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   489
25258
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   490
    private MethodHandle getDynamicMethodInvocation(final CallSiteDescriptor callSiteDescriptor,
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   491
            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
   492
        final DynamicMethod dynaMethod = getDynamicMethod(methodName, methodMap);
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   493
        return dynaMethod != null ? dynaMethod.getInvocation(callSiteDescriptor, linkerServices) : null;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   494
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   495
25258
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   496
    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
   497
        final DynamicMethod dynaMethod = methodMap.get(methodName);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   498
        return dynaMethod != null ? dynaMethod : getExplicitSignatureDynamicMethod(methodName, methodMap);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   499
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   500
25258
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   501
    private SingleDynamicMethod getExplicitSignatureDynamicMethod(final String fullName,
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   502
            final Map<String, DynamicMethod> methodsMap) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   503
        // 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
   504
        // 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
   505
        // 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
   506
        // 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
   507
        // 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
   508
        // for performance reasons.
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   509
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   510
        // 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
   511
        final int lastChar = fullName.length() - 1;
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   512
        if(fullName.charAt(lastChar) != ')') {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   513
            return null;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   514
        }
25258
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   515
        final int openBrace = fullName.indexOf('(');
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   516
        if(openBrace == -1) {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   517
            return null;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   518
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   519
25258
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   520
        final String name = fullName.substring(0, openBrace);
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   521
        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
   522
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   523
        // 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
   524
        final DynamicMethod simpleNamedMethod = methodsMap.get(name);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   525
        if(simpleNamedMethod == null) {
25258
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   526
            // explicit signature constructor access
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   527
            // 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
   528
            // 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
   529
            if (name.isEmpty()) {
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   530
                return getConstructorMethod(signature);
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   531
            }
325380d7c38c 8049242: Explicit constructor overload selection should work with StaticClass as well
sundar
parents: 25252
diff changeset
   532
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   533
            return null;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   534
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   535
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   536
        // 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
   537
        return simpleNamedMethod.getMethodForExactParamTypes(signature);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   538
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   539
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   540
    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
   541
            boolean.class, MethodHandle.class));
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   542
    private static final MethodHandle CONSTANT_NULL_DROP_METHOD_HANDLE = MethodHandles.dropArguments(
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   543
            MethodHandles.constant(Object.class, null), 0, MethodHandle.class);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   544
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   545
    private GuardedInvocationComponent getPropertySetter(final ComponentLinkRequest req) throws Exception {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   546
        if (req.name == null) {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   547
            return getUnnamedPropertySetter(req);
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   548
        }
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   549
        return getNamedPropertySetter(req);
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   550
    }
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   551
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   552
    private GuardedInvocationComponent getUnnamedPropertySetter(final ComponentLinkRequest req) throws Exception {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   553
        final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   554
        // 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
   555
        assertParameterCount(callSiteDescriptor, 3);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   556
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   557
        // 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
   558
        // 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
   559
        // 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
   560
        final MethodType origType = callSiteDescriptor.getMethodType();
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   561
        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
   562
        final LinkerServices linkerServices = req.linkerServices;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   563
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   564
        // What's below is basically:
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   565
        //   foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation),
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   566
        //     get_setter_handle(type, linkerServices))
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   567
        // 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
   568
        // 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
   569
        // component's invocation.
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   570
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   571
        // 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
   572
        // 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
   573
        // Object return type).
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   574
        final MethodType setterType = type.dropParameterTypes(1, 2);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   575
        // 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
   576
        // MethodHandle(Object, String, Object)
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   577
        final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0,
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   578
                callSiteDescriptor.changeMethodType(setterType), linkerServices);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   579
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   580
        // Cast getter to MethodHandle(O, N, V)
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   581
        final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType(
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   582
                MethodHandle.class));
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   583
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   584
        // 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
   585
        final MethodHandle invokeHandle = MethodHandles.exactInvoker(setterType);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   586
        // 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
   587
        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
   588
                1));
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   589
        final GuardedInvocationComponent nextComponent = getNextComponent(req);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   590
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   591
        final MethodHandle fallbackFolded;
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   592
        if (nextComponent == null) {
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   593
            // 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
   594
            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
   595
                    type.parameterList()).asType(type.insertParameterTypes(0, MethodHandle.class));
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   596
        } else {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   597
            // 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
   598
            // extra argument resulting from fold
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   599
            fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(),
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   600
                    0, MethodHandle.class);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   601
        }
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   602
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   603
        // 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
   604
        final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   605
                    IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   606
        if(nextComponent == null) {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   607
            return getClassGuardedInvocationComponent(compositeSetter, type);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   608
        }
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   609
        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
   610
    }
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   611
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   612
    private GuardedInvocationComponent getNamedPropertySetter(final ComponentLinkRequest req) throws Exception {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   613
        final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   614
        // 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
   615
        assertParameterCount(callSiteDescriptor, 2);
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   616
        final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, req.linkerServices,
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   617
                req.name.toString(), propertySetters);
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   618
        // 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
   619
        if(gi != null) {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   620
            return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   621
        }
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   622
        // If we don't have a property setter with this name, always fall back to the next namespace (if any).
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   623
        return getNextComponent(req);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   624
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   625
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   626
    private static final Lookup privateLookup = new Lookup(MethodHandles.lookup());
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   627
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   628
    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
   629
            boolean.class, AnnotatedDynamicMethod.class));
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   630
    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
   631
            MethodHandles.constant(Object.class, null), 0, AnnotatedDynamicMethod.class);
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   632
    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
   633
            "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
   634
    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
   635
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   636
    private GuardedInvocationComponent getPropertyGetter(final ComponentLinkRequest req) throws Exception {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   637
        if (req.name == null) {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   638
            return getUnnamedPropertyGetter(req);
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   639
        }
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   640
        return getNamedPropertyGetter(req);
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   641
    }
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   642
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   643
    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
   644
        // 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
   645
        // 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
   646
        // 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
   647
        final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   648
        final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   649
        // Must have exactly two arguments: receiver and name
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   650
        assertParameterCount(callSiteDescriptor, 2);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   651
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   652
        // What's below is basically:
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   653
        //   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
   654
        // 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
   655
        // 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
   656
        // or delegate to next component's invocation.
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   657
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   658
        final LinkerServices linkerServices = req.linkerServices;
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   659
        final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType(
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   660
                AnnotatedDynamicMethod.class));
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   661
        final MethodHandle callSiteBoundMethodGetter = MethodHandles.insertArguments(
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   662
                GET_ANNOTATED_METHOD, 1, callSiteDescriptor, linkerServices);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   663
        final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0,
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   664
                callSiteBoundMethodGetter);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   665
        // Object(AnnotatedDynamicMethod, Object)->Object(AnnotatedDynamicMethod, T0)
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   666
        final MethodHandle invokeHandleTyped = linkerServices.asType(callSiteBoundInvoker,
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   667
                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
   668
        // 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
   669
        // Object(AnnotatedDynamicMethod, T0)->Object(AnnotatedDynamicMethod, T0, T1)
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   670
        final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2,
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   671
                type.parameterType(1));
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   672
        final GuardedInvocationComponent nextComponent = getNextComponent(req);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   673
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   674
        final MethodHandle fallbackFolded;
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   675
        if(nextComponent == null) {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   676
            // 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
   677
            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
   678
                    type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedDynamicMethod.class));
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   679
        } else {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   680
            // 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
   681
            // 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
   682
            final MethodHandle nextInvocation = nextComponent.getGuardedInvocation().getInvocation();
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   683
            final MethodType nextType = nextInvocation.type();
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   684
            fallbackFolded = MethodHandles.dropArguments(nextInvocation.asType(
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   685
                    nextType.changeReturnType(Object.class)), 0, AnnotatedDynamicMethod.class);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   686
        }
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   687
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   688
        // fold(Object(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1))
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   689
        final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   690
                    IS_ANNOTATED_METHOD_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   691
        if(nextComponent == null) {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   692
            return getClassGuardedInvocationComponent(compositeGetter, type);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   693
        }
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   694
        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
   695
    }
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   696
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   697
    private GuardedInvocationComponent getNamedPropertyGetter(final ComponentLinkRequest req) throws Exception {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   698
        final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   699
        // Must have exactly one argument: receiver
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   700
        assertParameterCount(callSiteDescriptor, 1);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   701
        // Fixed name
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   702
        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
   703
        if(annGetter == null) {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   704
            // 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
   705
            return getNextComponent(req);
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   706
        }
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   707
        final MethodHandle getter = annGetter.getInvocation(req);
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   708
        // 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
   709
        // 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
   710
        // 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
   711
        // 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
   712
        // 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
   713
        // value is null.
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   714
        final ValidationType validationType = annGetter.validationType;
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   715
        // 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
   716
        return new GuardedInvocationComponent(getter, getGuard(validationType,
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   717
                callSiteDescriptor.getMethodType()), clazz, validationType);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   718
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   719
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   720
    private MethodHandle getGuard(final ValidationType validationType, final MethodType methodType) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   721
        switch(validationType) {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   722
            case EXACT_CLASS: {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   723
                return getClassGuard(methodType);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   724
            }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   725
            case INSTANCE_OF: {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   726
                return getAssignableGuard(methodType);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   727
            }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   728
            case IS_ARRAY: {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   729
                return Guards.isArray(0, methodType);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   730
            }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   731
            case NONE: {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   732
                return null;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   733
            }
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   734
            default: {
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   735
                throw new AssertionError();
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   736
            }
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   737
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   738
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   739
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   740
    private static final MethodHandle IS_DYNAMIC_METHOD = Guards.isInstance(DynamicMethod.class,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   741
            MethodType.methodType(boolean.class, Object.class));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   742
    private static final MethodHandle OBJECT_IDENTITY = MethodHandles.identity(Object.class);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   743
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   744
    private GuardedInvocationComponent getMethodGetter(final ComponentLinkRequest req) throws Exception {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   745
        if (req.name == null) {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   746
            return getUnnamedMethodGetter(req);
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   747
        }
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   748
        return getNamedMethodGetter(req);
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   749
    }
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   750
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   751
    private static MethodType getMethodGetterType(final ComponentLinkRequest req) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   752
        // The created method handle will always return a DynamicMethod (or null), but since we don't want that type to
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   753
        // 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
   754
        return req.getDescriptor().getMethodType().changeReturnType(Object.class);
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   755
    }
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   756
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   757
    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
   758
        // Must have exactly two arguments: receiver and name
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   759
        assertParameterCount(req.getDescriptor(), 2);
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   760
        final GuardedInvocationComponent nextComponent = getNextComponent(req);
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   761
        final LinkerServices linkerServices = req.linkerServices;
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   762
        final MethodType type = getMethodGetterType(req);
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   763
        if(nextComponent == null) {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   764
            // 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
   765
            return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   766
        }
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   767
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   768
        // What's below is basically:
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   769
        // 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
   770
        // 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
   771
        // 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
   772
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   773
        final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   774
        // 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
   775
        final MethodHandle returnMethodHandle = linkerServices.asType(MethodHandles.dropArguments(
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   776
                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
   777
        final MethodHandle nextComponentInvocation = nextComponent.getGuardedInvocation().getInvocation();
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   778
        // 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
   779
        // return type.
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   780
        assert nextComponentInvocation.type().changeReturnType(type.returnType()).equals(type);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   781
        // 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
   782
        final MethodHandle nextCombinedInvocation = MethodHandles.dropArguments(nextComponentInvocation, 0,
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   783
                Object.class);
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   784
        // 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
   785
        // 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
   786
        final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   787
                IS_DYNAMIC_METHOD, returnMethodHandle,
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   788
                nextCombinedInvocation.asType(nextCombinedInvocation.type().changeReturnType(Object.class))),
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   789
                typedGetter);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   790
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   791
        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
   792
    }
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   793
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   794
    private GuardedInvocationComponent getNamedMethodGetter(final ComponentLinkRequest req)
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   795
            throws Exception {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   796
        // Must have exactly one argument: receiver
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   797
        assertParameterCount(req.getDescriptor(), 1);
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   798
        final DynamicMethod method = getDynamicMethod(req.name.toString());
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   799
        if(method == null) {
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   800
            // 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
   801
            return getNextComponent(req);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   802
        }
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   803
        // No delegation to the next namespace; if we have a method with that name, we'll always return it at
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   804
        // this point.
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   805
        final MethodType type = getMethodGetterType(req);
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   806
        return getClassGuardedInvocationComponent(req.linkerServices.asType(MethodHandles.dropArguments(
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   807
                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
   808
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   809
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   810
    static class MethodPair {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   811
        final MethodHandle method1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   812
        final MethodHandle method2;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   813
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   814
        MethodPair(final MethodHandle method1, final MethodHandle method2) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   815
            this.method1 = method1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   816
            this.method2 = method2;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   817
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   818
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   819
        MethodHandle guardWithTest(final MethodHandle test) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   820
            return MethodHandles.guardWithTest(test, method1, method2);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   821
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   822
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   823
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   824
    static MethodPair matchReturnTypes(final MethodHandle m1, final MethodHandle m2) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   825
        final MethodType type1 = m1.type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   826
        final MethodType type2 = m2.type();
33338
faf6471e1cc8 8139887: Reduce visibility of few methods in TypeUtilities and Guards API
attila
parents: 33337
diff changeset
   827
        final Class<?> commonRetType = InternalTypeUtilities.getCommonLosslessConversionType(type1.returnType(),
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   828
                type2.returnType());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   829
        return new MethodPair(
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   830
                m1.asType(type1.changeReturnType(commonRetType)),
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   831
                m2.asType(type2.changeReturnType(commonRetType)));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   832
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   833
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   834
    private static void assertParameterCount(final CallSiteDescriptor descriptor, final int paramCount) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   835
        if(descriptor.getMethodType().parameterCount() != paramCount) {
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33338
diff changeset
   836
            throw new BootstrapMethodError(descriptor.getOperation() + " must have exactly " + paramCount + " parameters.");
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   837
        }
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
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   840
    private static MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   841
            "getPropertyGetterHandle", Object.class, Object.class), 1, Object.class);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   842
    private final MethodHandle getPropertyGetterHandle = GET_PROPERTY_GETTER_HANDLE.bindTo(this);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   843
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   844
    /**
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   845
     * @param id the property ID
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   846
     * @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
   847
     */
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   848
    @SuppressWarnings("unused")
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   849
    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
   850
        return propertyGetters.get(String.valueOf(id));
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   851
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   852
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   853
    // 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
   854
    // 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
   855
    // a typical property setter with variable name signature (target, name, value).
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   856
    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
   857
            privateLookup.findOwnSpecial("getPropertySetterHandle", MethodHandle.class, CallSiteDescriptor.class,
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   858
                    LinkerServices.class, Object.class), 3, Object.class), 5, Object.class);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   859
    // Type is MethodHandle(MethodType, LinkerServices, Object, String, Object)
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   860
    private final MethodHandle getPropertySetterHandle = GET_PROPERTY_SETTER_HANDLE.bindTo(this);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   861
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   862
    @SuppressWarnings("unused")
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   863
    private MethodHandle getPropertySetterHandle(final CallSiteDescriptor setterDescriptor, final LinkerServices linkerServices,
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   864
            final Object id) {
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   865
        return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   866
    }
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
    private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   869
            "getDynamicMethod", Object.class, Object.class), 1, Object.class);
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   870
    private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   871
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   872
    @SuppressWarnings("unused")
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   873
    // This method is marked to return Object instead of DynamicMethod as it's used as a linking component and we don't
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 19630
diff changeset
   874
    // want to make the DynamicMethod type observable externally (e.g. as the return type of a MethodHandle returned for
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 37379
diff changeset
   875
    // GET:METHOD linking).
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   876
    private Object getDynamicMethod(final Object name) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   877
        return getDynamicMethod(String.valueOf(name), methods);
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
    /**
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   881
     * Returns a dynamic method of the specified name.
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   882
     *
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   883
     * @param name name of the method
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   884
     * @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
   885
     * method with the specified name does not exist.
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   886
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   887
    DynamicMethod getDynamicMethod(final String name) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   888
        return getDynamicMethod(name, methods);
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
    /**
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   892
     * 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
   893
     * 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
   894
     * creating more stable call sites.
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   895
     * @param getter the getter
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   896
     * @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
   897
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   898
    private static Method getMostGenericGetter(final Method getter) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   899
        return getMostGenericGetter(getter.getName(), getter.getReturnType(), getter.getDeclaringClass());
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   900
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   901
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   902
    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
   903
        if(declaringClass == null) {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   904
            return null;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   905
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   906
        // Prefer interfaces
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   907
        for(final Class<?> itf: declaringClass.getInterfaces()) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   908
            final Method itfGetter = getMostGenericGetter(name, returnType, itf);
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   909
            if(itfGetter != null) {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   910
                return itfGetter;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   911
            }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   912
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   913
        final Method superGetter = getMostGenericGetter(name, returnType, declaringClass.getSuperclass());
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   914
        if(superGetter != null) {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   915
            return superGetter;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   916
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   917
        if(!CheckRestrictedPackage.isRestrictedClass(declaringClass)) {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   918
            try {
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   919
                return declaringClass.getMethod(name);
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   920
            } catch(final NoSuchMethodException e) {
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   921
                // Intentionally ignored, meant to fall through
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   922
            }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   923
        }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   924
        return null;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   925
    }
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   926
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   927
    private static final class AnnotatedDynamicMethod {
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   928
        private final SingleDynamicMethod method;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   929
        /*private*/ final ValidationType validationType;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   930
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24719
diff changeset
   931
        AnnotatedDynamicMethod(final SingleDynamicMethod method, final ValidationType validationType) {
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   932
            this.method = method;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   933
            this.validationType = validationType;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   934
        }
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   935
34978
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   936
        MethodHandle getInvocation(final ComponentLinkRequest req) {
e753c4c9f96f 8144917: Prepare AbstractJavaLinker/BeanLinker codebase for missing member implementation
attila
parents: 34842
diff changeset
   937
            return method.getInvocation(req.getDescriptor(), req.linkerServices);
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   938
        }
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   939
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   940
        @SuppressWarnings("unused")
33331
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 33330
diff changeset
   941
        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
   942
            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
   943
            assert inv != null;
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   944
            return inv;
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 16267
diff changeset
   945
        }
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents:
diff changeset
   946
    }
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16234
diff changeset
   947
}