nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
author sundar
Wed, 17 Sep 2014 15:02:42 +0530
changeset 26651 c04136234037
parent 25865 d38d876f1654
child 27099 eceb216332cb
permissions -rw-r--r--
8058615: Overload resolution ambiguity involving ConsString Reviewed-by: lagergren, hannesw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
21686
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     1
/*
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     4
 *
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    10
 *
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    15
 * accompanied this code).
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    16
 *
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    20
 *
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    23
 * questions.
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    24
 */
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    25
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime.linker;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    27
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    28
import java.lang.invoke.MethodHandle;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    29
import java.lang.invoke.MethodHandles;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    30
import java.lang.invoke.MethodType;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    31
import jdk.internal.dynalink.beans.BeansLinker;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    32
import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    33
import jdk.internal.dynalink.linker.GuardedInvocation;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    34
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    35
import jdk.internal.dynalink.linker.LinkRequest;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    36
import jdk.internal.dynalink.linker.LinkerServices;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    37
import jdk.internal.dynalink.support.Lookup;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    38
import jdk.nashorn.internal.runtime.ConsString;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    39
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    40
/**
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    41
 * This linker delegates to a {@code BeansLinker} but passes it a special linker services object that has a modified
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    42
 * {@code asType} method that will ensure that we never pass internal engine objects that should not be externally
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    43
 * observable (currently only ConsString) to Java APIs, but rather that we flatten it into a String. We can't just add
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    44
 * this functionality as custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    45
 * the target method handle parameter signature is {@code Object}.
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    46
 */
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    47
public class NashornBeansLinker implements GuardingDynamicLinker {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    48
    private static final MethodHandle EXPORT_ARGUMENT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportArgument", Object.class, Object.class);
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    49
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    50
    private final BeansLinker beansLinker = new BeansLinker();
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    51
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    52
    @Override
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    53
    public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    54
        return getGuardedInvocation(beansLinker, linkRequest, linkerServices);
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    55
    }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    56
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    57
    /**
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    58
     * Delegates to the specified linker but injects its linker services wrapper so that it will apply all special
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    59
     * conversions that this class does.
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    60
     * @param delegateLinker the linker to which the actual work is delegated to.
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    61
     * @param linkRequest the delegated link request
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    62
     * @param linkerServices the original link services that will be augmented with special conversions
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    63
     * @return the guarded invocation from the delegate, possibly augmented with special conversions
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    64
     * @throws Exception if the delegate throws an exception
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    65
     */
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    66
    public static GuardedInvocation getGuardedInvocation(final GuardingDynamicLinker delegateLinker, final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    67
        return delegateLinker.getGuardedInvocation(linkRequest, new NashornBeansLinkerServices(linkerServices));
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    68
    }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    69
24754
c43ab71d68f5 8043004: Reduce variability at JavaAdapter call sites
attila
parents: 24719
diff changeset
    70
    static Object exportArgument(final Object arg) {
21686
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    71
        return arg instanceof ConsString ? arg.toString() : arg;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    72
    }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    73
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    74
    private static class NashornBeansLinkerServices implements LinkerServices {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    75
        private final LinkerServices linkerServices;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    76
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    77
        NashornBeansLinkerServices(final LinkerServices linkerServices) {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    78
            this.linkerServices = linkerServices;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    79
        }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    80
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    81
        @Override
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    82
        public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    83
            final MethodHandle typed = linkerServices.asType(handle, fromType);
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    84
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    85
            final MethodType handleType = handle.type();
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    86
            final int paramCount = handleType.parameterCount();
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    87
            assert fromType.parameterCount() == handleType.parameterCount();
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    88
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    89
            MethodHandle[] filters = null;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    90
            for(int i = 0; i < paramCount; ++i) {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    91
                if(shouldConvert(handleType.parameterType(i), fromType.parameterType(i))) {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    92
                    if(filters == null) {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    93
                        filters = new MethodHandle[paramCount];
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    94
                    }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    95
                    filters[i] = EXPORT_ARGUMENT;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    96
                }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    97
            }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    98
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
    99
            return filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   100
        }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   101
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21686
diff changeset
   102
        @Override
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 24754
diff changeset
   103
        public MethodHandle asTypeLosslessReturn(final MethodHandle handle, final MethodType fromType) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21686
diff changeset
   104
            return Implementation.asTypeLosslessReturn(this, handle, fromType);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21686
diff changeset
   105
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21686
diff changeset
   106
21686
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   107
        private static boolean shouldConvert(final Class<?> handleType, final Class<?> fromType) {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   108
            return handleType == Object.class && fromType == Object.class;
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   109
        }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   110
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   111
        @Override
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   112
        public MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   113
            return linkerServices.getTypeConverter(sourceType, targetType);
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   114
        }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   115
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   116
        @Override
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   117
        public boolean canConvert(final Class<?> from, final Class<?> to) {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   118
            return linkerServices.canConvert(from, to);
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   119
        }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   120
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   121
        @Override
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   122
        public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception {
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   123
            return linkerServices.getGuardedInvocation(linkRequest);
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   124
        }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   125
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   126
        @Override
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   127
        public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
26651
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   128
            if (sourceType == ConsString.class) {
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   129
                if (String.class == targetType1 || CharSequence.class == targetType1) {
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   130
                    return Comparison.TYPE_1_BETTER;
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   131
                }
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   132
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   133
                if (String.class == targetType2 || CharSequence.class == targetType2) {
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   134
                    return Comparison.TYPE_2_BETTER;
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   135
                }
c04136234037 8058615: Overload resolution ambiguity involving ConsString
sundar
parents: 25865
diff changeset
   136
            }
21686
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   137
            return linkerServices.compareConversion(sourceType, targetType1, targetType2);
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   138
        }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   139
    }
5c6946f97d6f 8027236: Ensure ScriptObject and ConsString aren't visible to Java
attila
parents:
diff changeset
   140
}