8139919: Make CallSiteDescriptor a concrete class
Reviewed-by: hannesw, lagergren, sundar
This commit is contained in:
parent
b49c5c8b09
commit
df445c6578
@ -89,30 +89,42 @@ import java.lang.invoke.MethodType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.StringTokenizer;
|
||||
import jdk.internal.dynalink.support.NameCodec;
|
||||
|
||||
/**
|
||||
* Interface for objects containing the information necessary for linking a call
|
||||
* site. This information is normally passed as parameters to bootstrap methods
|
||||
* and consists of the {@code MethodHandles.Lookup} object on the caller class
|
||||
* in which the call site occurs, the method name mentioned in the call site,
|
||||
* and the method type of the call site. {@code CallSiteDescriptor} objects are
|
||||
* used in Dynalink to capture and store these parameters for subsequent use by
|
||||
* the {@link DynamicLinker}.
|
||||
* Call site descriptors contain all the information necessary for linking a
|
||||
* call site. This information is normally passed as parameters to bootstrap
|
||||
* methods and consists of the {@code MethodHandles.Lookup} object on the caller
|
||||
* class in which the call site occurs, the method name mentioned in the call
|
||||
* site, and the method type of the call site. {@code CallSiteDescriptor}
|
||||
* objects are used in Dynalink to capture and store these parameters for
|
||||
* subsequent use by the {@link DynamicLinker}.
|
||||
* <p>
|
||||
* The constructors of built-in {@link RelinkableCallSite} implementations all
|
||||
* take a call site descriptor.
|
||||
* <p>
|
||||
* Call site descriptors must be immutable.
|
||||
* Call site descriptors must be immutable. You can use this class as-is or you
|
||||
* can subclass it, especially if you need to add further information to the
|
||||
* descriptors (typically, values passed in additional parameters to the
|
||||
* bootstrap method) or want to cache results of name tokenization. Since the
|
||||
* descriptors must be immutable, you can set up a cache for equivalent
|
||||
* descriptors to have the call sites share them.
|
||||
*/
|
||||
public interface CallSiteDescriptor {
|
||||
public class CallSiteDescriptor {
|
||||
private final MethodHandles.Lookup lookup;
|
||||
private final String name;
|
||||
private final MethodType methodType;
|
||||
|
||||
/**
|
||||
* A runtime permission to invoke the {@link #getLookup()} method. It is
|
||||
* named {@code "dynalink.getLookup"}.
|
||||
* The name of a runtime permission to invoke the {@link #getLookup()}
|
||||
* method.
|
||||
*/
|
||||
public static final RuntimePermission GET_LOOKUP_PERMISSION =
|
||||
new RuntimePermission("dynalink.getLookup");
|
||||
public static final String GET_LOOKUP_PERMISSION_NAME = "dynalink.getLookup";
|
||||
|
||||
private static final RuntimePermission GET_LOOKUP_PERMISSION = new RuntimePermission(GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
/**
|
||||
* The index of the name token that will carry the operation scheme prefix,
|
||||
@ -145,68 +157,139 @@ public interface CallSiteDescriptor {
|
||||
*/
|
||||
public static final String OPERATOR_DELIMITER = "|";
|
||||
|
||||
/**
|
||||
* Creates a new call site descriptor.
|
||||
* @param lookup the lookup object describing the class the call site belongs to.
|
||||
* @param name the name of the method at the call site.
|
||||
* @param methodType the method type of the call site.
|
||||
*/
|
||||
public CallSiteDescriptor(final Lookup lookup, final String name, final MethodType methodType) {
|
||||
this.lookup = Objects.requireNonNull(lookup, "lookup");
|
||||
this.name = Objects.requireNonNull(name, "name");
|
||||
this.methodType = Objects.requireNonNull(methodType, "methodType");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of tokens in the name of the method at the call site.
|
||||
* Method names are tokenized with the {@link #TOKEN_DELIMITER} character
|
||||
* character, e.g. {@code "dyn:getProp:color"} would be the name used to
|
||||
* describe a method that retrieves the property named "color" on the object
|
||||
* it is invoked on.
|
||||
* it is invoked on. This method will count the tokens in the name on every
|
||||
* invocation. Subclasses can override this method with a more efficient
|
||||
* implementation that caches the tokens.
|
||||
* @return the number of tokens in the name of the method at the call site.
|
||||
*/
|
||||
public int getNameTokenCount();
|
||||
public int getNameTokenCount() {
|
||||
return getNameTokenizer().countTokens();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <i>i<sup>th</sup></i> token in the method name at the call
|
||||
* site. Method names are tokenized with the {@link #TOKEN_DELIMITER}
|
||||
* character.
|
||||
* character. This method will tokenize the name on every invocation.
|
||||
* Subclasses can override this method with a more efficient implementation
|
||||
* that caches the tokens.
|
||||
* @param i the index of the token. Must be between 0 (inclusive) and
|
||||
* {@link #getNameTokenCount()} (exclusive).
|
||||
* @throws IllegalArgumentException if the index is outside the allowed
|
||||
* @throws NoSuchElementException if the index is outside the allowed
|
||||
* range.
|
||||
* @return the <i>i<sup>th</sup></i> token in the method name at the call
|
||||
* site.
|
||||
*/
|
||||
public String getNameToken(int i);
|
||||
public String getNameToken(final int i) {
|
||||
final StringTokenizer tok = getNameTokenizer();
|
||||
for (int j = 0; j < i; ++j) {
|
||||
tok.nextToken();
|
||||
}
|
||||
final String token = tok.nextToken();
|
||||
return (i > 1 ? NameCodec.decode(token) : token).intern();
|
||||
}
|
||||
|
||||
private StringTokenizer getNameTokenizer() {
|
||||
return getNameTokenizer(name);
|
||||
}
|
||||
|
||||
private static StringTokenizer getNameTokenizer(final String name) {
|
||||
return new StringTokenizer(name, CallSiteDescriptor.TOKEN_DELIMITER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full (untokenized) name of the method at the call site.
|
||||
* @return the full (untokenized) name of the method at the call site.
|
||||
*/
|
||||
public String getName();
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the method at the call site.
|
||||
*
|
||||
* @return type of the method at the call site.
|
||||
*/
|
||||
public MethodType getMethodType();
|
||||
public final MethodType getMethodType() {
|
||||
return methodType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lookup that should be used to find method handles to set as
|
||||
* targets of the call site described by this descriptor. When creating
|
||||
* descriptors from a {@link java.lang.invoke} bootstrap method, it should
|
||||
* be the lookup passed to the bootstrap. An implementation should use
|
||||
* {@link #checkLookup(MethodHandles.Lookup)} to ensure the necessary
|
||||
* security properties.
|
||||
* be the lookup passed to the bootstrap.
|
||||
* @return the lookup that should be used to find method handles to set as
|
||||
* targets of the call site described by this descriptor.
|
||||
* @throws SecurityException if the lookup isn't the
|
||||
* {@link MethodHandles#publicLookup()} and a security manager is present,
|
||||
* and a check for {@code RuntimePermission("dynalink.getLookup")}
|
||||
* (a canonical instance of which is available as
|
||||
* {@link #GET_LOOKUP_PERMISSION}) fails.
|
||||
* and a check for {@code RuntimePermission("dynalink.getLookup")} fails.
|
||||
*/
|
||||
public Lookup getLookup();
|
||||
public final Lookup getLookup() {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null && lookup != MethodHandles.publicLookup()) {
|
||||
sm.checkPermission(GET_LOOKUP_PERMISSION);
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of {@link #getLookup()} without a security check. Can
|
||||
* be used by subclasses to access the lookup quickly.
|
||||
* @return same as returned value of {@link #getLookup()}.
|
||||
*/
|
||||
protected final Lookup getLookupPrivileged() {
|
||||
return lookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new call site descriptor from this descriptor, which is
|
||||
* identical to this, except it changes the method type.
|
||||
* identical to this, except it changes the method type. Subclasses must
|
||||
* override the
|
||||
*
|
||||
* @param newMethodType the new method type
|
||||
* @return a new call site descriptor, with the method type changed.
|
||||
*/
|
||||
public CallSiteDescriptor changeMethodType(MethodType newMethodType);
|
||||
public final CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
|
||||
final CallSiteDescriptor changed = Objects.requireNonNull(
|
||||
changeMethodTypeInternal(newMethodType),
|
||||
"changeMethodTypeInternal() must not return null.");
|
||||
|
||||
if (getClass() != changed.getClass()) {
|
||||
throw new RuntimeException(
|
||||
"changeMethodTypeInternal() must return an object of the same class it is invoked on.");
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new call site descriptor from this descriptor, which is
|
||||
* identical to this, except it changes the method type. Subclasses must
|
||||
* override this method to return an object of their exact class.
|
||||
*
|
||||
* @param newMethodType the new method type
|
||||
* @return a new call site descriptor, with the method type changed.
|
||||
*/
|
||||
protected CallSiteDescriptor changeMethodTypeInternal(final MethodType newMethodType) {
|
||||
return new CallSiteDescriptor(lookup, name, newMethodType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenizes a composite operation name of this descriptor along
|
||||
@ -215,7 +298,7 @@ public interface CallSiteDescriptor {
|
||||
* {@code ["getElem", "getProp", "getMethod"]}.
|
||||
* @return a list of operator tokens.
|
||||
*/
|
||||
public default List<String> tokenizeOperators() {
|
||||
public final List<String> tokenizeOperators() {
|
||||
final String ops = getNameToken(CallSiteDescriptor.OPERATOR);
|
||||
final StringTokenizer tok = new StringTokenizer(ops, CallSiteDescriptor.OPERATOR_DELIMITER);
|
||||
final int count = tok.countTokens();
|
||||
@ -229,29 +312,6 @@ public interface CallSiteDescriptor {
|
||||
return Arrays.asList(tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current access context is granted the
|
||||
* {@code RuntimePermission("dynalink.getLookup")} permission, if the
|
||||
* system contains a security manager, and the passed lookup is not the
|
||||
* {@link MethodHandles#publicLookup()}. This method should be used in all
|
||||
* implementations of {@link #getLookup()} method to ensure that only
|
||||
* code with permission can retrieve the lookup object.
|
||||
* @param lookup the lookup being checked for access
|
||||
* @return the passed in lookup if there's either no security manager in
|
||||
* the system, or the passed lookup is the public lookup, or the current
|
||||
* access context is granted the relevant permission.
|
||||
* @throws SecurityException if the system contains a security manager, and
|
||||
* the passed lookup is not the public lookup, and the current access
|
||||
* context is not granted the relevant permission.
|
||||
*/
|
||||
public static Lookup checkLookup(final Lookup lookup) {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null && lookup != MethodHandles.publicLookup()) {
|
||||
sm.checkPermission(GET_LOOKUP_PERMISSION);
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenizes the composite name along {@link #TOKEN_DELIMITER} characters,
|
||||
* as well as {@link NameCodec#decode(String) demangles} and interns the
|
||||
@ -263,7 +323,7 @@ public interface CallSiteDescriptor {
|
||||
* @return an array of unmangled, interned tokens.
|
||||
*/
|
||||
public static String[] tokenizeName(final String name) {
|
||||
final StringTokenizer tok = new StringTokenizer(name, CallSiteDescriptor.TOKEN_DELIMITER);
|
||||
final StringTokenizer tok = getNameTokenizer(name);
|
||||
final String[] tokens = new String[tok.countTokens()];
|
||||
for(int i = 0; i < tokens.length; ++i) {
|
||||
String token = tok.nextToken();
|
||||
@ -274,4 +334,60 @@ public interface CallSiteDescriptor {
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
} else if (obj == null) {
|
||||
return false;
|
||||
} else if (obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
final CallSiteDescriptor other = (CallSiteDescriptor)obj;
|
||||
return name.equals(other.name) && methodType.equals(other.methodType) &&
|
||||
lookupsEqual(lookup, other.lookup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two lookup objects for value-based equality. They are considered
|
||||
* equal if they have the same
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#lookupClass()} and
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#lookupModes()}.
|
||||
* @param l1 first lookup
|
||||
* @param l2 second lookup
|
||||
* @return true if the two lookups are equal, false otherwise.
|
||||
*/
|
||||
private static boolean lookupsEqual(final Lookup l1, final Lookup l2) {
|
||||
return l1.lookupClass() == l2.lookupClass() && l1.lookupModes() == l2.lookupModes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode() + 31 * methodType.hashCode() + 31 * 31 * lookupHashCode(lookup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value-based hash code for the passed lookup object. It is
|
||||
* based on the lookup object's
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#lookupClass()} and
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#lookupModes()} values.
|
||||
* @param lookup the lookup object.
|
||||
* @return a hash code for the object..
|
||||
*/
|
||||
protected static int lookupHashCode(final Lookup lookup) {
|
||||
return lookup.lookupClass().hashCode() + 31 * lookup.lookupModes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of this call site descriptor, of the
|
||||
* format {@code name(parameterTypes)returnType@lookup}.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final String mt = methodType.toString();
|
||||
final String l = lookup.toString();
|
||||
final StringBuilder b = new StringBuilder(name.length() + mt.length() + 1 + l.length());
|
||||
return b.append(name).append(mt).append("@").append(l).toString();
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,6 @@ import jdk.internal.dynalink.linker.LinkerServices;
|
||||
import jdk.internal.dynalink.linker.support.Lookup;
|
||||
import jdk.internal.dynalink.linker.support.SimpleLinkRequest;
|
||||
import jdk.internal.dynalink.support.ChainedCallSite;
|
||||
import jdk.internal.dynalink.support.SimpleCallSiteDescriptor;
|
||||
import jdk.internal.dynalink.support.SimpleRelinkableCallSite;
|
||||
|
||||
/**
|
||||
@ -124,7 +123,7 @@ import jdk.internal.dynalink.support.SimpleRelinkableCallSite;
|
||||
* }
|
||||
*
|
||||
* public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) {
|
||||
* return dynamicLinker.link(new SimpleRelinkableCallSite(new SimpleCallSiteDescriptor(lookup, name, type)));
|
||||
* return dynamicLinker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(lookup, name, type)));
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
@ -153,12 +152,7 @@ import jdk.internal.dynalink.support.SimpleRelinkableCallSite;
|
||||
* <li>You also need to provide {@link CallSiteDescriptor}s to your call sites.
|
||||
* They are immutable objects that contain all the information about the call
|
||||
* site: the class performing the lookups, the name of the method being invoked,
|
||||
* and the method signature. The library provides a
|
||||
* {@link SimpleCallSiteDescriptor}, or you can create your own descriptor
|
||||
* classes, especially if you need to add further information to them
|
||||
* (typically, values passed in additional parameters to the bootstrap method).
|
||||
* Since they are specified to be immutable, you can set up a cache for
|
||||
* equivalent descriptors to have the call sites share them.</li>
|
||||
* and the method signature.</li>
|
||||
*
|
||||
* </ul>
|
||||
*/
|
||||
|
@ -107,7 +107,7 @@ import jdk.internal.dynalink.linker.support.Lookup;
|
||||
class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
|
||||
private static final AccessControlContext GET_LOOKUP_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext(
|
||||
CallSiteDescriptor.GET_LOOKUP_PERMISSION);
|
||||
CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
// Typed as "AccessibleObject" as it can be either a method or a constructor.
|
||||
// If we were Java8-only, we could use java.lang.reflect.Executable
|
||||
|
@ -232,8 +232,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
||||
|
||||
private static final AccessControlContext GET_CALL_SITE_CLASS_LOADER_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext(
|
||||
new RuntimePermission("getClassLoader"),
|
||||
CallSiteDescriptor.GET_LOOKUP_PERMISSION);
|
||||
"getClassLoader", CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
private static ClassLoader getCallSiteClassLoader(final CallSiteDescriptor callSiteDescriptor) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
|
@ -145,7 +145,7 @@
|
||||
* public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) {
|
||||
* return dynamicLinker.link(
|
||||
* new SimpleRelinkableCallSite(
|
||||
* new SimpleCallSiteDescriptor(lookup, name, type)));
|
||||
* new CallSiteDescriptor(lookup, name, type)));
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
@ -166,9 +166,7 @@
|
||||
* are two implementations already provided by the library.</li>
|
||||
* <li>Finally, Dynalink uses {@link jdk.internal.dynalink.CallSiteDescriptor} objects to
|
||||
* preserve the parameters to the bootstrap method as it will need them whenever
|
||||
* it needs to relink a call site. Again,
|
||||
* {@link jdk.internal.dynalink.support.SimpleCallSiteDescriptor} is a simple
|
||||
* implementation already provided by the library.</li>
|
||||
* it needs to relink a call site.</li>
|
||||
* </ul>
|
||||
* <p>What can you already do with the above setup? {@code DynamicLinkerFactory}
|
||||
* by default creates a {@code DynamicLinker} that can link Java objects with the
|
||||
|
@ -1,250 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file, and Oracle licenses the original version of this file under the BSD
|
||||
* license:
|
||||
*/
|
||||
/*
|
||||
Copyright 2009-2013 Attila Szegedi
|
||||
|
||||
Licensed under both the Apache License, Version 2.0 (the "Apache License")
|
||||
and the BSD License (the "BSD License"), with licensee being free to
|
||||
choose either of the two at their discretion.
|
||||
|
||||
You may not use this file except in compliance with either the Apache
|
||||
License or the BSD License.
|
||||
|
||||
If you choose to use this file in compliance with the Apache License, the
|
||||
following notice applies to you:
|
||||
|
||||
You may obtain a copy of the Apache License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
permissions and limitations under the License.
|
||||
|
||||
If you choose to use this file in compliance with the BSD License, the
|
||||
following notice applies to you:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the names of
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package jdk.internal.dynalink.support;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
|
||||
/**
|
||||
* A base class for call site descriptor implementations. Provides
|
||||
* reconstruction of the name from the tokens, as well as generally useful
|
||||
* {@code equals}, {@code hashCode}, and {@code toString} methods. In order to
|
||||
* both prevent unprivileged access to its internal {@link MethodHandles.Lookup}
|
||||
* object, and at the same time not force privileged access to it from
|
||||
* {@code equals}, {@code hashCode}, and {@code toString} methods, subclasses
|
||||
* must implement {@link #lookupEquals(AbstractCallSiteDescriptor)},
|
||||
* {@link #lookupHashCode()} and {@link #lookupToString()} methods.
|
||||
* Additionally, {@link #equalsInKind(AbstractCallSiteDescriptor)} should be
|
||||
* overridden instead of {@link #equals(Object)} to compare descriptors in
|
||||
* subclasses; it is only necessary if they have implementation-specific
|
||||
* properties other than the standard name, type, and lookup.
|
||||
* @param <T> The call site descriptor subclass
|
||||
*/
|
||||
public abstract class AbstractCallSiteDescriptor<T extends AbstractCallSiteDescriptor<T>> implements CallSiteDescriptor {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return appendName(new StringBuilder(getNameLength())).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this call site descriptor is equality to another object. It is
|
||||
* considered equal iff and only if they belong to the exact same class, and
|
||||
* have the same name, method type, and lookup. Subclasses with additional
|
||||
* properties should override
|
||||
* {@link #equalsInKind(AbstractCallSiteDescriptor)} instead of this method.
|
||||
* @param obj the object checked for equality
|
||||
* @return true if they are equal, false otherwise
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return obj != null && obj.getClass() == getClass() && equalsInKind((T)obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this call site descriptor is equal to the passed,
|
||||
* non-null call site descriptor of the same class.
|
||||
* @param csd the other call site descriptor.
|
||||
* @return true if they are equal.
|
||||
*/
|
||||
protected boolean equalsInKind(final T csd) {
|
||||
if(csd == this) {
|
||||
return true;
|
||||
}
|
||||
final int ntc = getNameTokenCount();
|
||||
if(ntc != csd.getNameTokenCount()) {
|
||||
return false;
|
||||
}
|
||||
for(int i = ntc; i-- > 0;) { // Reverse order as variability is higher at the end
|
||||
if(!Objects.equals(getNameToken(i), csd.getNameToken(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(!getMethodType().equals(csd.getMethodType())) {
|
||||
return false;
|
||||
}
|
||||
return lookupEquals(csd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this call site descriptor's lookup is equal to the other
|
||||
* call site descriptor's lookup. Typical implementation should try to
|
||||
* obtain the other lookup directly without going through privileged
|
||||
* {@link #getLookup()} (e.g. by reading the field as the type system
|
||||
* enforces that they are of the same class) and then delegate to
|
||||
* {@link #lookupsEqual(MethodHandles.Lookup, MethodHandles.Lookup)}.
|
||||
* @param other the other lookup
|
||||
* @return true if the lookups are equal
|
||||
*/
|
||||
protected abstract boolean lookupEquals(T other);
|
||||
|
||||
/**
|
||||
* Compares two lookup objects for value-based equality. They are considered
|
||||
* equal if they have the same
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#lookupClass()} and
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#lookupModes()}.
|
||||
* @param l1 first lookup
|
||||
* @param l2 second lookup
|
||||
* @return true if the two lookups are equal, false otherwise.
|
||||
*/
|
||||
protected static boolean lookupsEqual(final Lookup l1, final Lookup l2) {
|
||||
if(l1 == l2) {
|
||||
return true;
|
||||
} else if (l1 == null || l2 == null) {
|
||||
return false;
|
||||
} else if(l1.lookupClass() != l2.lookupClass()) {
|
||||
return false;
|
||||
}
|
||||
return l1.lookupModes() == l2.lookupModes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = lookupHashCode();
|
||||
final int c = getNameTokenCount();
|
||||
for(int i = 0; i < c; ++i) {
|
||||
h = h * 31 + getNameToken(i).hashCode();
|
||||
}
|
||||
return h * 31 + getMethodType().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hash code of this call site descriptor's {@link Lookup}
|
||||
* object. Typical implementation should delegate to
|
||||
* {@link #lookupHashCode(MethodHandles.Lookup)}.
|
||||
* @return the hash code of this call site descriptor's {@link Lookup}
|
||||
* object.
|
||||
*/
|
||||
protected abstract int lookupHashCode();
|
||||
|
||||
/**
|
||||
* Returns a value-based hash code for the passed lookup object. It is
|
||||
* based on the lookup object's
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#lookupClass()} and
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#lookupModes()} values.
|
||||
* @param lookup the lookup object.
|
||||
* @return a hash code for the object. Returns 0 for null.
|
||||
*/
|
||||
protected static int lookupHashCode(final Lookup lookup) {
|
||||
return lookup != null ? lookup.lookupClass().hashCode() + 31 * lookup.lookupModes() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final String mt = getMethodType().toString();
|
||||
final String l = lookupToString();
|
||||
final StringBuilder b = new StringBuilder(l.length() + 1 + mt.length() + getNameLength());
|
||||
return appendName(b).append(mt).append("@").append(l).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this call site descriptor's
|
||||
* {@link Lookup} object. Typically will return
|
||||
* {@link java.lang.invoke.MethodHandles.Lookup#toString()}.
|
||||
* @return a string representation of this call site descriptor's
|
||||
* {@link Lookup} object.
|
||||
*/
|
||||
protected abstract String lookupToString();
|
||||
|
||||
private int getNameLength() {
|
||||
final int c = getNameTokenCount();
|
||||
int l = 0;
|
||||
for(int i = 0; i < c; ++i) {
|
||||
l += getNameToken(i).length();
|
||||
}
|
||||
return l + c - 1;
|
||||
}
|
||||
|
||||
private StringBuilder appendName(final StringBuilder b) {
|
||||
b.append(getNameToken(0));
|
||||
final int c = getNameTokenCount();
|
||||
for(int i = 1; i < c; ++i) {
|
||||
b.append(':').append(getNameToken(i));
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file, and Oracle licenses the original version of this file under the BSD
|
||||
* license:
|
||||
*/
|
||||
/*
|
||||
Copyright 2015 Attila Szegedi
|
||||
|
||||
Licensed under both the Apache License, Version 2.0 (the "Apache License")
|
||||
and the BSD License (the "BSD License"), with licensee being free to
|
||||
choose either of the two at their discretion.
|
||||
|
||||
You may not use this file except in compliance with either the Apache
|
||||
License or the BSD License.
|
||||
|
||||
If you choose to use this file in compliance with the Apache License, the
|
||||
following notice applies to you:
|
||||
|
||||
You may obtain a copy of the Apache License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
permissions and limitations under the License.
|
||||
|
||||
If you choose to use this file in compliance with the BSD License, the
|
||||
following notice applies to you:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the names of
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package jdk.internal.dynalink.support;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
|
||||
/**
|
||||
* A simple implementation of the call site descriptor. It stores the lookup, the name, and the method type.
|
||||
* Even if you roll your own implementation of {@link CallSiteDescriptor}, you might want to use
|
||||
* {@link CallSiteDescriptor#checkLookup(MethodHandles.Lookup)} as a ready-made utility method to ensure you're handing
|
||||
* out lookup objects securely.
|
||||
*/
|
||||
public class SimpleCallSiteDescriptor extends AbstractCallSiteDescriptor<SimpleCallSiteDescriptor> {
|
||||
private final Lookup lookup;
|
||||
private final String[] tokenizedName;
|
||||
private final MethodType methodType;
|
||||
|
||||
/**
|
||||
* Creates a new simple call site descriptor.
|
||||
* @param lookup the lookup at the call site, as passed to the bootstrap method. Must not be null.
|
||||
* @param name the name of the operation at the call site, as passed to the bootstrap method. Must not be null.
|
||||
* @param methodType the signature of operation at the call site, as passed to the bootstrap method. Must not be null.
|
||||
*/
|
||||
public SimpleCallSiteDescriptor(final Lookup lookup, final String name, final MethodType methodType) {
|
||||
this(Objects.requireNonNull(lookup, "lookup"),
|
||||
CallSiteDescriptor.tokenizeName(Objects.requireNonNull(name, "name")),
|
||||
Objects.requireNonNull(methodType, "methodType"));
|
||||
}
|
||||
|
||||
private SimpleCallSiteDescriptor(final Lookup lookup, final String[] tokenizedName, final MethodType methodType) {
|
||||
this.lookup = lookup;
|
||||
this.tokenizedName = tokenizedName;
|
||||
this.methodType = methodType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNameTokenCount() {
|
||||
return tokenizedName.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameToken(final int i) {
|
||||
try {
|
||||
return tokenizedName[i];
|
||||
} catch(final ArrayIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodType getMethodType() {
|
||||
return methodType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Lookup getLookup() {
|
||||
return CallSiteDescriptor.checkLookup(lookup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
|
||||
return new SimpleCallSiteDescriptor(lookup, tokenizedName, newMethodType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean lookupEquals(final SimpleCallSiteDescriptor other) {
|
||||
return AbstractCallSiteDescriptor.lookupsEqual(lookup, other.lookup);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int lookupHashCode() {
|
||||
return AbstractCallSiteDescriptor.lookupHashCode(lookup);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String lookupToString() {
|
||||
return lookup.toString();
|
||||
}
|
||||
}
|
@ -128,7 +128,7 @@ public class ScriptFunction extends ScriptObject {
|
||||
private static final Object LAZY_PROTOTYPE = new Object();
|
||||
|
||||
private static final AccessControlContext GET_LOOKUP_PERMISSION_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION);
|
||||
AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
private static PropertyMap createStrictModeMap(final PropertyMap map) {
|
||||
final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
|
||||
|
@ -96,7 +96,7 @@ final class JavaSuperAdapterLinker implements TypeBasedGuardingDynamicLinker {
|
||||
CallSiteDescriptor.NAME_OPERAND)) : DYN_GET_METHOD;
|
||||
|
||||
final CallSiteDescriptor newDescriptor = NashornCallSiteDescriptor.get(
|
||||
NashornCallSiteDescriptor.getLookupPrivileged(descriptor), opName,
|
||||
NashornCallSiteDescriptor.getLookupInternal(descriptor), opName,
|
||||
type.changeParameterType(0, adapterClass), 0);
|
||||
|
||||
// Delegate to BeansLinker
|
||||
|
@ -109,7 +109,7 @@ public class NashornBeansLinker implements GuardingDynamicLinker {
|
||||
final MethodType callType = desc.getMethodType();
|
||||
// drop callee (Undefined ScriptFunction) and change the request to be dyn:callMethod:<name>
|
||||
final NashornCallSiteDescriptor newDesc = NashornCallSiteDescriptor.get(
|
||||
NashornCallSiteDescriptor.getLookupPrivileged(desc), "dyn:callMethod:" + name,
|
||||
NashornCallSiteDescriptor.getLookupInternal(desc), "dyn:callMethod:" + name,
|
||||
desc.getMethodType().dropParameterTypes(1, 2),
|
||||
NashornCallSiteDescriptor.getFlags(desc));
|
||||
final GuardedInvocation gi = getGuardedInvocation(beansLinker,
|
||||
|
@ -34,7 +34,6 @@ import java.security.PrivilegedAction;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import jdk.internal.dynalink.support.AbstractCallSiteDescriptor;
|
||||
import jdk.nashorn.internal.ir.debug.NashornTextifier;
|
||||
import jdk.nashorn.internal.runtime.AccessControlContextFactory;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
@ -44,7 +43,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
* we can have a more compact representation, as we know that we're always only using {@code "dyn:*"} operations; also
|
||||
* we're storing flags in an additional primitive field.
|
||||
*/
|
||||
public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor<NashornCallSiteDescriptor> {
|
||||
public final class NashornCallSiteDescriptor extends CallSiteDescriptor {
|
||||
/** Flags that the call site references a scope variable (it's an identifier reference or a var declaration, not a
|
||||
* property access expression. */
|
||||
public static final int CALLSITE_SCOPE = 1 << 0;
|
||||
@ -109,12 +108,10 @@ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor<
|
||||
};
|
||||
|
||||
private static final AccessControlContext GET_LOOKUP_PERMISSION_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION);
|
||||
AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
private final MethodHandles.Lookup lookup;
|
||||
private final String operator;
|
||||
private final String operand;
|
||||
private final MethodType methodType;
|
||||
private final int flags;
|
||||
|
||||
/**
|
||||
@ -161,12 +158,12 @@ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor<
|
||||
assert "dyn".equals(tokenizedName[0]);
|
||||
assert tokenizedName[1] != null;
|
||||
// TODO: see if we can move mangling/unmangling into Dynalink
|
||||
return get(lookup, tokenizedName[1], tokenizedName.length == 3 ? tokenizedName[2].intern() : null,
|
||||
return get(lookup, name, tokenizedName[1], tokenizedName.length == 3 ? tokenizedName[2].intern() : null,
|
||||
methodType, flags);
|
||||
}
|
||||
|
||||
private static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final String operator, final String operand, final MethodType methodType, final int flags) {
|
||||
final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(lookup, operator, operand, methodType, flags);
|
||||
private static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final String name, final String operator, final String operand, final MethodType methodType, final int flags) {
|
||||
final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(lookup, name, operator, operand, methodType, flags);
|
||||
// Many of these call site descriptors are identical (e.g. every getter for a property color will be
|
||||
// "dyn:getProp:color(Object)Object", so it makes sense canonicalizing them.
|
||||
final ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor> classCanonicals = canonicals.get(lookup.lookupClass());
|
||||
@ -174,12 +171,11 @@ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor<
|
||||
return canonical != null ? canonical : csd;
|
||||
}
|
||||
|
||||
private NashornCallSiteDescriptor(final MethodHandles.Lookup lookup, final String operator, final String operand,
|
||||
private NashornCallSiteDescriptor(final MethodHandles.Lookup lookup, final String name, final String operator, final String operand,
|
||||
final MethodType methodType, final int flags) {
|
||||
this.lookup = lookup;
|
||||
super(lookup, name, methodType);
|
||||
this.operator = operator;
|
||||
this.operand = operand;
|
||||
this.methodType = methodType;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
@ -197,34 +193,25 @@ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor<
|
||||
if(operand != null) {
|
||||
return operand;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw new IndexOutOfBoundsException(String.valueOf(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lookup getLookup() {
|
||||
return CallSiteDescriptor.checkLookup(lookup);
|
||||
}
|
||||
|
||||
static Lookup getLookupPrivileged(final CallSiteDescriptor csd) {
|
||||
static Lookup getLookupInternal(final CallSiteDescriptor csd) {
|
||||
if (csd instanceof NashornCallSiteDescriptor) {
|
||||
return ((NashornCallSiteDescriptor)csd).lookup;
|
||||
return ((NashornCallSiteDescriptor)csd).getLookupPrivileged();
|
||||
}
|
||||
return AccessController.doPrivileged((PrivilegedAction<Lookup>)()->csd.getLookup(),
|
||||
GET_LOOKUP_PERMISSION_CONTEXT);
|
||||
return AccessController.doPrivileged((PrivilegedAction<Lookup>)()->csd.getLookup(), GET_LOOKUP_PERMISSION_CONTEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean equalsInKind(final NashornCallSiteDescriptor csd) {
|
||||
return super.equalsInKind(csd) && flags == csd.flags;
|
||||
public boolean equals(final Object obj) {
|
||||
return super.equals(obj) && flags == ((NashornCallSiteDescriptor)obj).flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodType getMethodType() {
|
||||
return methodType;
|
||||
public int hashCode() {
|
||||
return super.hashCode() ^ flags;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,23 +445,7 @@ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor<
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
|
||||
return get(lookup, operator, operand, newMethodType, flags);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean lookupEquals(final NashornCallSiteDescriptor other) {
|
||||
return AbstractCallSiteDescriptor.lookupsEqual(lookup, other.lookup);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int lookupHashCode() {
|
||||
return AbstractCallSiteDescriptor.lookupHashCode(lookup);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String lookupToString() {
|
||||
return lookup.toString();
|
||||
public CallSiteDescriptor changeMethodTypeInternal(final MethodType newMethodType) {
|
||||
return get(getLookupPrivileged(), getName(), operator, operand, newMethodType, flags);
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ import jdk.nashorn.internal.runtime.Undefined;
|
||||
*/
|
||||
final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
|
||||
private static final AccessControlContext GET_LOOKUP_PERMISSION_CONTEXT =
|
||||
AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION);
|
||||
AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
private static final ClassValue<MethodHandle> ARRAY_CONVERTERS = new ClassValue<MethodHandle>() {
|
||||
@Override
|
||||
|
@ -82,7 +82,7 @@ final class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker {
|
||||
// Change this link request into a link request on the adapter class.
|
||||
final Object[] args = request.getArguments();
|
||||
args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null,
|
||||
NashornCallSiteDescriptor.getLookupPrivileged(request.getCallSiteDescriptor()));
|
||||
NashornCallSiteDescriptor.getLookupInternal(request.getCallSiteDescriptor()));
|
||||
final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
|
||||
final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
|
||||
// Finally, modify the guard to test for the original abstract class.
|
||||
|
Loading…
Reference in New Issue
Block a user