nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
author attila
Fri, 25 Apr 2014 14:20:07 +0200
changeset 24205 0a7fbab84fb0
parent 23375 a1110f2cbe75
child 24769 de4dcfa9380f
permissions -rw-r--r--
8034967: Reduce access to Nashorn internals Reviewed-by: ahgross, jlaskey, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime.linker;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
16277
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents: 16272
diff changeset
    28
import static jdk.nashorn.internal.lookup.Lookup.MH;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    30
import java.lang.invoke.MethodHandle;
18841
9bbc4b8832b2 8010946: AccessControl.doPrivileged is broken when called from js script
attila
parents: 17769
diff changeset
    31
import java.lang.invoke.MethodHandles;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
    32
import java.lang.invoke.MethodHandles.Lookup;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import java.lang.invoke.MethodType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import java.lang.reflect.Modifier;
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
    35
import java.security.AccessControlContext;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
import java.security.AccessController;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
    37
import java.security.CodeSigner;
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
    38
import java.security.CodeSource;
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
    39
import java.security.Permissions;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import java.security.PrivilegedAction;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
    41
import java.security.ProtectionDomain;
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    42
import java.util.ArrayList;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import java.util.Arrays;
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    44
import java.util.Collections;
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    45
import java.util.HashMap;
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    46
import java.util.List;
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    47
import java.util.Map;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
    48
import java.util.concurrent.ConcurrentHashMap;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16221
diff changeset
    49
import jdk.internal.dynalink.beans.StaticClass;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16221
diff changeset
    50
import jdk.internal.dynalink.support.LinkRequestImpl;
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
    51
import jdk.nashorn.internal.runtime.Context;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import jdk.nashorn.internal.runtime.ECMAException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
import jdk.nashorn.internal.runtime.ScriptFunction;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
import jdk.nashorn.internal.runtime.ScriptObject;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
/**
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16256
diff changeset
    57
 * <p>A factory class that generates adapter classes. Adapter classes allow implementation of Java interfaces and
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    58
 * extending of Java classes from JavaScript. For every combination of a superclass to extend and interfaces to
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    59
 * implement (collectively: "original types"), exactly one adapter class is generated that extends the specified
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
    60
 * superclass and implements the specified interfaces. (But see the discussion of class-based overrides for exceptions.)
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    61
 * </p><p>
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
 * The adapter class is generated in a new secure class loader that inherits Nashorn's protection domain, and has either
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    63
 * one of the original types' class loader or the Nashorn's class loader as its parent - the parent class loader
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    64
 * is chosen so that all the original types and the Nashorn core classes are visible from it (as the adapter will have
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    65
 * constant pool references to ScriptObject and ScriptFunction classes). In case none of the candidate class loaders has
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
    66
 * visibility of all the required types, an error is thrown. The class uses {@link JavaAdapterBytecodeGenerator} to
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
    67
 * generate the adapter class itself; see its documentation for details about the generated class.
16167
d99db3541813 8005983: JavaAdapterFactory generated proxy classes should take extra constructor arguments at the end
attila
parents: 16151
diff changeset
    68
 * </p><p>
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
 * You normally don't use this class directly, but rather either create adapters from script using
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
    70
 * {@link jdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
    71
 * {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
 * types.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
 * </p>
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 16777
diff changeset
    76
@SuppressWarnings("javadoc")
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16178
diff changeset
    77
public final class JavaAdapterFactory {
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
    78
    private static final ProtectionDomain MINIMAL_PERMISSION_DOMAIN = createMinimalPermissionDomain();
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
    79
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
    80
    // context with permissions needs for AdapterInfo creation
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
    81
    private static final AccessControlContext CREATE_ADAPTER_INFO_ACC_CTXT =
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
    82
        ClassAndLoader.createPermAccCtxt("createClassLoader", "getClassLoader",
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
    83
            "accessDeclaredMembers", "accessClassInPackage.jdk.nashorn.internal.runtime");
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
    84
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    85
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    86
     * A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    87
     */
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    88
    private static final ClassValue<Map<List<Class<?>>, AdapterInfo>> ADAPTER_INFO_MAPS = new ClassValue<Map<List<Class<?>>, AdapterInfo>>() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
        @Override
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    90
        protected Map<List<Class<?>>, AdapterInfo> computeValue(final Class<?> type) {
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    91
            return new HashMap<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    92
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
    };
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    94
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
    /**
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    96
     * Returns an adapter class for the specified original types. The adapter class extends/implements the original
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    97
     * class/interfaces.
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    98
     * @param types the original types. The caller must pass at least one Java type representing either a public
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
    99
     * interface or a non-final public class with at least one public or protected constructor. If more than one type is
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   100
     * specified, at most one can be a class and the rest have to be interfaces. The class can be in any position in the
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   101
     * array. Invoking the method twice with exactly the same types in the same order will return the same adapter
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   102
     * class, any reordering of types or even addition or removal of redundant types (i.e. interfaces that other types
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   103
     * in the list already implement/extend, or {@code java.lang.Object} in a list of types consisting purely of
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   104
     * interfaces) will result in a different adapter class, even though those adapter classes are functionally
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   105
     * identical; we deliberately don't want to incur the additional processing cost of canonicalizing type lists.
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   106
     * @param classOverrides a JavaScript object with functions serving as the class-level overrides and
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   107
     * implementations. These overrides are defined for all instances of the class, and can be further overridden on a
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   108
     * per-instance basis by passing additional objects in the constructor.
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   109
     * @param lookup the lookup object identifying the caller class. The generated adapter class will have the
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   110
     * protection domain of the caller class iff the lookup object is full-strength, otherwise it will be completely
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   111
     * unprivileged.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   112
     * @return an adapter class. See this class' documentation for details on the generated adapter class.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   113
     * @throws ECMAException with a TypeError if the adapter class can not be generated because the original class is
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   114
     * final, non-public, or has no public or protected constructors.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
     */
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   116
    public static StaticClass getAdapterClassFor(final Class<?>[] types, ScriptObject classOverrides, final MethodHandles.Lookup lookup) {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   117
        return getAdapterClassFor(types, classOverrides, getProtectionDomain(lookup));
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   118
    }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   119
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   120
    private static StaticClass getAdapterClassFor(final Class<?>[] types, ScriptObject classOverrides, final ProtectionDomain protectionDomain) {
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   121
        assert types != null && types.length > 0;
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18841
diff changeset
   122
        final SecurityManager sm = System.getSecurityManager();
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18841
diff changeset
   123
        if (sm != null) {
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
   124
            for (Class<?> type : types) {
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18841
diff changeset
   125
                // check for restricted package access
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 19459
diff changeset
   126
                Context.checkPackageAccess(type);
22667
280928d0d6c8 8032954: Nashorn: extend Java.extend
sundar
parents: 20567
diff changeset
   127
                // check for classes, interfaces in reflection
22668
245094625886 8032948: Nashorn linkages awry
sundar
parents: 22667
diff changeset
   128
                ReflectionCheckLinker.checkReflectionAccess(type, true);
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18841
diff changeset
   129
            }
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18841
diff changeset
   130
        }
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   131
        return getAdapterInfo(types).getAdapterClass(classOverrides, protectionDomain);
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   132
    }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   133
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   134
    private static ProtectionDomain getProtectionDomain(final MethodHandles.Lookup lookup) {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   135
        if((lookup.lookupModes() & Lookup.PRIVATE) == 0) {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   136
            return MINIMAL_PERMISSION_DOMAIN;
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   137
        }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   138
        return getProtectionDomain(lookup.lookupClass());
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   139
    }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   140
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   141
    private static ProtectionDomain getProtectionDomain(final Class<?> clazz) {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   142
        return AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   143
            @Override
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   144
            public ProtectionDomain run() {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   145
                return clazz.getProtectionDomain();
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   146
            }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   147
        });
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   148
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   149
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   150
    /**
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   151
     * Returns a method handle representing a constructor that takes a single argument of the source type (which,
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   152
     * really, should be one of {@link ScriptObject}, {@link ScriptFunction}, or {@link Object}, and returns an instance
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   153
     * of the adapter for the target type. Used to implement the function autoconverters as well as the Nashorn's
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   154
     * JSR-223 script engine's {@code getInterface()} method.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   155
     * @param sourceType the source type; should be either {@link ScriptObject}, {@link ScriptFunction}, or
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   156
     * {@link Object}. In case of {@code Object}, it will return a method handle that dispatches to either the script
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   157
     * object or function constructor at invocation based on the actual argument.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   158
     * @param targetType the target type, for which adapter instances will be created
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   159
     * @return the constructor method handle.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   160
     * @throws Exception if anything goes wrong
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   161
     */
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   162
    public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType, final MethodHandles.Lookup lookup) throws Exception {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   163
        final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType }, null, lookup);
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   164
        return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   165
                NashornCallSiteDescriptor.get(lookup, "dyn:new",
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   166
                        MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   167
                        adapterClass, null)).getInvocation(), adapterClass);
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   168
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   169
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   170
    /**
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   171
     * Returns whether an instance of the specified class/interface can be generated from a ScriptFunction. Returns true
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   172
     * iff: the adapter for the class/interface can be created, it is abstract (this includes interfaces), it has at
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   173
     * least one abstract method, all the abstract methods share the same name, and it has a public or protected default
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   174
     * constructor. Note that invoking this class will most likely result in the adapter class being defined in the JVM
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   175
     * if it hasn't been already.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   176
     * @param clazz the inspected class
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   177
     * @return true iff an instance of the specified class/interface can be generated from a ScriptFunction.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   178
     */
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   179
    static boolean isAutoConvertibleFromFunction(final Class<?> clazz) {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   180
        return getAdapterInfo(new Class<?>[] { clazz }).autoConvertibleFromFunction;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   181
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   182
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   183
    private static AdapterInfo getAdapterInfo(final Class<?>[] types) {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   184
        final ClassAndLoader definingClassAndLoader = ClassAndLoader.getDefiningClassAndLoader(types);
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   185
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   186
        final Map<List<Class<?>>, AdapterInfo> adapterInfoMap = ADAPTER_INFO_MAPS.get(definingClassAndLoader.getRepresentativeClass());
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   187
        final List<Class<?>> typeList = types.length == 1 ? getSingletonClassList(types[0]) : Arrays.asList(types.clone());
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   188
        AdapterInfo adapterInfo;
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   189
        synchronized(adapterInfoMap) {
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   190
            adapterInfo = adapterInfoMap.get(typeList);
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   191
            if(adapterInfo == null) {
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   192
                adapterInfo = createAdapterInfo(types, definingClassAndLoader);
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   193
                adapterInfoMap.put(typeList, adapterInfo);
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   194
            }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   195
        }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   196
        return adapterInfo;
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   197
    }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   198
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   199
    @SuppressWarnings({ "unchecked", "rawtypes" })
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   200
    private static List<Class<?>> getSingletonClassList(final Class<?> clazz) {
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   201
        return (List)Collections.singletonList(clazz);
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   202
    }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   203
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   204
   /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   205
     * For a given class, create its adapter class and associated info.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
     * @param type the class for which the adapter is created
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   207
     * @return the adapter info for the class.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   208
     */
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   209
    private static AdapterInfo createAdapterInfo(final Class<?>[] types, final ClassAndLoader definingClassAndLoader) {
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   210
        Class<?> superClass = null;
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   211
        final List<Class<?>> interfaces = new ArrayList<>(types.length);
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   212
        for(final Class<?> t: types) {
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   213
            final int mod = t.getModifiers();
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   214
            if(!t.isInterface()) {
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   215
                if(superClass != null) {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   216
                    return new AdapterInfo(AdaptationResult.Outcome.ERROR_MULTIPLE_SUPERCLASSES, t.getCanonicalName() + " and " + superClass.getCanonicalName());
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   217
                }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   218
                if (Modifier.isFinal(mod)) {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   219
                    return new AdapterInfo(AdaptationResult.Outcome.ERROR_FINAL_CLASS, t.getCanonicalName());
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   220
                }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   221
                superClass = t;
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   222
            } else {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   223
                if (interfaces.size() > 65535) {
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   224
                    throw new IllegalArgumentException("interface limit exceeded");
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   225
                }
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   226
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   227
                interfaces.add(t);
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   228
            }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   229
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   230
            if(!Modifier.isPublic(mod)) {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   231
                return new AdapterInfo(AdaptationResult.Outcome.ERROR_NON_PUBLIC_CLASS, t.getCanonicalName());
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   232
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   233
        }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   234
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   235
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   236
        final Class<?> effectiveSuperClass = superClass == null ? Object.class : superClass;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
        return AccessController.doPrivileged(new PrivilegedAction<AdapterInfo>() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   239
            public AdapterInfo run() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   240
                try {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   241
                    return new AdapterInfo(effectiveSuperClass, interfaces, definingClassAndLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
                } catch (final AdaptationException e) {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   243
                    return new AdapterInfo(e.getAdaptationResult());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   244
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   245
            }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19456
diff changeset
   246
        }, CREATE_ADAPTER_INFO_ACC_CTXT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   247
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   248
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   249
    private static class AdapterInfo {
24205
0a7fbab84fb0 8034967: Reduce access to Nashorn internals
attila
parents: 23375
diff changeset
   250
        private static final ClassAndLoader SCRIPT_OBJECT_LOADER = new ClassAndLoader(ScriptFunction.class, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   251
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   252
        private final ClassLoader commonLoader;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   253
        // TODO: soft reference the JavaAdapterClassLoader objects. They can be recreated when needed.
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   254
        private final JavaAdapterClassLoader classAdapterGenerator;
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   255
        private final JavaAdapterClassLoader instanceAdapterGenerator;
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   256
        private final Map<CodeSource, StaticClass> instanceAdapters = new ConcurrentHashMap<>();
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   257
        final boolean autoConvertibleFromFunction;
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   258
        final AdaptationResult adaptationResult;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   260
        AdapterInfo(Class<?> superClass, List<Class<?>> interfaces, ClassAndLoader definingLoader) throws AdaptationException {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   261
            this.commonLoader = findCommonLoader(definingLoader);
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   262
            final JavaAdapterBytecodeGenerator gen = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, false);
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   263
            this.autoConvertibleFromFunction = gen.isAutoConvertibleFromFunction();
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   264
            instanceAdapterGenerator = gen.createAdapterClassLoader();
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   265
            this.classAdapterGenerator = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, true).createAdapterClassLoader();
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   266
            this.adaptationResult = AdaptationResult.SUCCESSFUL_RESULT;
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   267
        }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   268
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   269
        AdapterInfo(final AdaptationResult.Outcome outcome, final String classList) {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   270
            this(new AdaptationResult(outcome, classList));
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   271
        }
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   272
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   273
        AdapterInfo(final AdaptationResult adaptationResult) {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   274
            this.commonLoader = null;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   275
            this.classAdapterGenerator = null;
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   276
            this.instanceAdapterGenerator = null;
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   277
            this.autoConvertibleFromFunction = false;
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   278
            this.adaptationResult = adaptationResult;
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   279
        }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   280
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   281
        StaticClass getAdapterClass(final ScriptObject classOverrides, final ProtectionDomain protectionDomain) {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   282
            if(adaptationResult.getOutcome() != AdaptationResult.Outcome.SUCCESS) {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   283
                throw adaptationResult.typeError();
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   284
            }
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   285
            return classOverrides == null ? getInstanceAdapterClass(protectionDomain) :
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   286
                getClassAdapterClass(classOverrides, protectionDomain);
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   287
        }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   288
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   289
        private StaticClass getInstanceAdapterClass(final ProtectionDomain protectionDomain) {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   290
            CodeSource codeSource = protectionDomain.getCodeSource();
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   291
            if(codeSource == null) {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   292
                codeSource = MINIMAL_PERMISSION_DOMAIN.getCodeSource();
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   293
            }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   294
            StaticClass instanceAdapterClass = instanceAdapters.get(codeSource);
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   295
            if(instanceAdapterClass != null) {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   296
                return instanceAdapterClass;
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   297
            }
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   298
            // Any "unknown source" code source will default to no permission domain.
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   299
            final ProtectionDomain effectiveDomain = codeSource.equals(MINIMAL_PERMISSION_DOMAIN.getCodeSource()) ?
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   300
                    MINIMAL_PERMISSION_DOMAIN : protectionDomain;
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   301
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   302
            instanceAdapterClass = instanceAdapterGenerator.generateClass(commonLoader, effectiveDomain);
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   303
            final StaticClass existing = instanceAdapters.putIfAbsent(codeSource, instanceAdapterClass);
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   304
            return existing == null ? instanceAdapterClass : existing;
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   305
        }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   306
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   307
        private StaticClass getClassAdapterClass(final ScriptObject classOverrides, final ProtectionDomain protectionDomain) {
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   308
            JavaAdapterServices.setClassOverrides(classOverrides);
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   309
            try {
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   310
                return classAdapterGenerator.generateClass(commonLoader, protectionDomain);
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   311
            } finally {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   312
                JavaAdapterServices.setClassOverrides(null);
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   313
            }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   314
        }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   315
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   316
        /**
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   317
         * Choose between the passed class loader and the class loader that defines the ScriptObject class, based on which
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   318
         * of the two can see the classes in both.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   319
         * @param classAndLoader the loader and a representative class from it that will be used to add the generated
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   320
         * adapter to its ADAPTER_INFO_MAPS.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   321
         * @return the class loader that sees both the specified class and Nashorn classes.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   322
         * @throws IllegalStateException if no such class loader is found.
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   323
         */
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   324
        private static ClassLoader findCommonLoader(final ClassAndLoader classAndLoader) throws AdaptationException {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   325
            if(classAndLoader.canSee(SCRIPT_OBJECT_LOADER)) {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   326
                return classAndLoader.getLoader();
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   327
            }
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   328
            if (SCRIPT_OBJECT_LOADER.canSee(classAndLoader)) {
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   329
                return SCRIPT_OBJECT_LOADER.getLoader();
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   330
            }
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   331
16777
207a993adb9a 8011544: Allow subclassing Java classes from script without creating instances
attila
parents: 16525
diff changeset
   332
            throw new AdaptationException(AdaptationResult.Outcome.ERROR_NO_COMMON_LOADER, classAndLoader.getRepresentativeClass().getCanonicalName());
16171
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   333
        }
90dcd4fc42f0 8006168: ability to generate multi-type Java adapters
attila
parents: 16167
diff changeset
   334
    }
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   335
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   336
    private static ProtectionDomain createMinimalPermissionDomain() {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   337
        // Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   338
        final Permissions permissions = new Permissions();
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   339
        permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.objects"));
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   340
        permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   341
        permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   342
        return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
75563515567f 8032681: Issues with Nashorn
attila
parents: 22668
diff changeset
   343
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   344
}