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