--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/CallSiteDescriptor.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/CallSiteDescriptor.java Mon Oct 19 08:45:29 2015 +0200
@@ -83,6 +83,7 @@
package jdk.internal.dynalink;
+import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
@@ -93,64 +94,79 @@
import jdk.internal.dynalink.support.NameCodec;
/**
- * An immutable descriptor of a call site. It is an immutable object that contains all the information about a call
- * site: the class performing the lookups, the name of the method being invoked, and the method signature. Call site descriptors are used in this library in place of passing a real call site to
- * guarding linkers so they aren't tempted to directly manipulate the call sites. The constructors of built-in
- * {@link RelinkableCallSite} implementations all need a call site descriptor. Even if you create your own call site
- * descriptors consider using {@link CallSiteDescriptor#tokenizeName(String)} in your implementation.
+ * Interface for objects describing a call site. A call site descriptor contains
+ * all the information about a call site necessary for linking it: the class
+ * performing the lookups, the name of the method being invoked, and the method
+ * signature. Call site descriptors are used in Dynalink in place of passing
+ * {@link CallSite} objects to linkers so they can't directly manipulate them.
+ * The constructors of built-in {@link RelinkableCallSite} implementations all
+ * take a call site descriptor. Call site descriptors must be immutable.
*/
public interface CallSiteDescriptor {
/**
- * A permission to invoke the {@link #getLookup()} method. It is named {@code "dynalink.getLookup"}.
+ * A runtime permission to invoke the {@link #getLookup()} method. It is
+ * named {@code "dynalink.getLookup"}.
*/
- public static final RuntimePermission GET_LOOKUP_PERMISSION = new RuntimePermission("dynalink.getLookup");
+ public static final RuntimePermission GET_LOOKUP_PERMISSION =
+ new RuntimePermission("dynalink.getLookup");
/**
- * The index of the name token that will carry the operation scheme prefix (usually, "dyn").
+ * The index of the name token that will carry the operation scheme prefix,
+ * e.g. {@code "dyn"} for operations specified by Dynalink itself.
*/
public static final int SCHEME = 0;
+
/**
- * The index of the name token that will usually carry the operation name.
+ * The index of the name token that carries the operation name, at least
+ * when using the {@code "dyn"} scheme.
*/
- public static final int OPERATOR=1;
- /**
- * The index of the name token that will usually carry a name of an operand (of a property, method, etc.)
- */
-
- public static final int NAME_OPERAND=2;
+ public static final int OPERATOR = 1;
/**
- * Character used to delimit tokens in an call site name.
+ * The index of the name token that carries the name of an operand (e.g. a
+ * property or a method), at least when using the {@code "dyn"} scheme.
+ */
+ public static final int NAME_OPERAND = 2;
+
+ /**
+ * String used to delimit tokens in a call site name; its value is
+ * {@code ":"}, that is the colon character.
*/
public static final String TOKEN_DELIMITER = ":";
/**
- * Character used to delimit operation names in a composite operation specification.
+ * String used to delimit operation names in a composite operation name;
+ * its value is {@code "|"}, that is the pipe character.
*/
public static final String OPERATOR_DELIMITER = "|";
/**
- * Returns the number of tokens in the name of the method at the call site. Method names are tokenized with the
- * colon ":" character, i.e. "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.
+ * 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.
* @return the number of tokens in the name of the method at the call site.
*/
public int getNameTokenCount();
/**
- * Returns the <i>i<sup>th</sup></i> token in the method name at the call site. Method names are tokenized with the
- * colon ":" character.
- * @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 range.
- * @return the <i>i<sup>th</sup></i> token in the method name at the call site. The returned strings are interned.
+ * 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.
+ * @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
+ * range.
+ * @return the <i>i<sup>th</sup></i> token in the method name at the call
+ * site.
*/
public String getNameToken(int i);
/**
- * Returns the name of the method at the call site. Note that the object internally only stores the tokenized name,
- * and has to reconstruct the full name from tokens on each invocation.
- * @return the name of the method at the call site.
+ * 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();
@@ -162,17 +178,25 @@
public MethodType getMethodType();
/**
- * Returns the lookup passed to the bootstrap method.
- * @return the lookup passed to the bootstrap method.
- * @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")} (available as
+ * 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.
+ * @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.
*/
public Lookup getLookup();
/**
- * Creates a new call site descriptor from this descriptor, which is identical to this, except it changes the method
- * type.
+ * Creates a new call site descriptor from this descriptor, which is
+ * identical to this, except it changes the method type.
*
* @param newMethodType the new method type
* @return a new call site descriptor, with the method type changed.
@@ -181,9 +205,11 @@
/**
- * Tokenizes a composite operation name along pipe characters. I.e. if you have a "dyn:getElem|getProp|getMethod"
- * operation, returns a list of ["getElem", "getProp", "getMethod"]. The tokens are not interned.
- * @return a list of tokens
+ * Tokenizes a composite operation name of this descriptor along
+ * {@link #OPERATOR_DELIMITER} characters. E.g. if this descriptor's name is
+ * {@code "dyn:getElem|getProp|getMethod"}, then it returns a list of
+ * {@code ["getElem", "getProp", "getMethod"]}.
+ * @return a list of operator tokens.
*/
public default List<String> tokenizeOperators() {
final String ops = getNameToken(CallSiteDescriptor.OPERATOR);
@@ -200,15 +226,19 @@
}
/**
- * 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()}.
+ * 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
- * {@link MethodHandles#publicLookup()}, and the current access context is not granted the relevant
- * permission.
+ * @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();
@@ -219,11 +249,14 @@
}
/**
- * Tokenizes the composite name along colons, as well as {@link NameCodec#decode(String) demangles} and interns
- * the tokens. The first two tokens are not demangled as they are supposed to be the naming scheme and the name of
- * the operation which can be expected to consist of just alphabetical characters.
- * @param name the composite name consisting of colon-separated, possibly mangled tokens.
- * @return an array of tokens
+ * Tokenizes the composite name along {@link #TOKEN_DELIMITER} characters,
+ * as well as {@link NameCodec#decode(String) demangles} and interns the
+ * tokens. The first two tokens are not demangled as they are supposed to
+ * be the naming scheme and the name of the operation which can be expected
+ * to consist of just alphabetical characters.
+ * @param name the composite name consisting of
+ * {@link #TOKEN_DELIMITER}-separated, possibly mangled tokens.
+ * @return an array of unmangled, interned tokens.
*/
public static String[] tokenizeName(final String name) {
final StringTokenizer tok = new StringTokenizer(name, CallSiteDescriptor.TOKEN_DELIMITER);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/ChainedCallSite.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/ChainedCallSite.java Mon Oct 19 08:45:29 2015 +0200
@@ -93,14 +93,21 @@
import jdk.internal.dynalink.support.Lookup;
/**
- * A relinkable call site that maintains a chain of linked method handles. In the default implementation, up to 8 method
- * handles can be chained, cascading from one to the other through
- * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}. When this call site has to link a new
- * method handle and the length of the chain is already at the maximum, it will throw away the oldest method handle.
- * Switchpoint-invalidated handles in the chain are removed eagerly (on each linking request, and whenever a
- * switchpoint-invalidated method handle is traversed during invocation). There is currently no profiling
- * attached to the handles in the chain, so they are never reordered based on usage; the most recently linked method
- * handle is always at the start of the chain.
+ * A relinkable call site that implements a polymorphic inline caching strategy.
+ * It remembers up to 8 {@link GuardedInvocation}s it was linked with, and on
+ * each relink request builds a cascading chain of method handles of one
+ * invocation falling back to the next one. The number of remembered invocations
+ * can be customized by overriding {@link #getMaxChainLength()} in a subclass.
+ * When this call site is relinked with a new invocation and the length of the
+ * chain is already at the maximum, it will throw away the oldest invocation.
+ * Invocations with invalidated switch points and ones for which their
+ * invalidating exception triggered are removed eagerly from the chain. The
+ * invocations are never reordered; the most recently linked method handle is
+ * always at the start of the chain and the least recently linked at its end.
+ * The call site can be safely relinked on more than one thread concurrently.
+ * Race conditions in linking are resolved by throwing away the
+ * {@link GuardedInvocation} produced on the losing thread without incorporating
+ * it into the chain, so it can lead to repeated linking for the same arguments.
*/
public class ChainedCallSite extends AbstractRelinkableCallSite {
private static final MethodHandle PRUNE_CATCHES;
@@ -130,22 +137,24 @@
}
/**
- * The maximum number of method handles in the chain. Defaults to 8. You can override it in a subclass if you need
- * to change the value. If your override returns a value less than 1, the code will break.
- * @return the maximum number of method handles in the chain.
+ * The maximum number of method handles in the chain. Defaults to 8. You can
+ * override it in a subclass if you need to change the value.
+ * @return the maximum number of method handles in the chain. The return
+ * value is checked, and if your override returns a value less than 1, a
+ * {@link RuntimeException} will be thrown.
*/
protected int getMaxChainLength() {
return 8;
}
@Override
- public void relink(final GuardedInvocation guardedInvocation, final MethodHandle fallback) {
- relinkInternal(guardedInvocation, fallback, false, false);
+ public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) {
+ relinkInternal(guardedInvocation, relinkAndInvoke, false, false);
}
@Override
- public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle fallback) {
- relinkInternal(guardedInvocation, fallback, true, false);
+ public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) {
+ relinkInternal(guardedInvocation, relinkAndInvoke, true, false);
}
private MethodHandle relinkInternal(final GuardedInvocation invocation, final MethodHandle relink, final boolean reset, final boolean removeCatches) {
@@ -216,12 +225,12 @@
/**
* Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that
* chain.
- * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink).
+ * @param relinkAndInvoke the ultimate fallback for the chain passed from the dynamic linker.
* @return a method handle for prune-and-invoke
*/
- private MethodHandle makePruneAndInvokeMethod(final MethodHandle relink, final MethodHandle prune) {
+ private MethodHandle makePruneAndInvokeMethod(final MethodHandle relinkAndInvoke, final MethodHandle prune) {
// Bind prune to (this, relink)
- final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relink);
+ final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relinkAndInvoke);
// Make it ignore all incoming arguments
final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList());
// Invoke prune, then invoke the call site target with original arguments
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinker.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinker.java Mon Oct 19 08:45:29 2015 +0200
@@ -97,14 +97,13 @@
import jdk.internal.dynalink.support.SimpleLinkRequest;
/**
- * The linker for {@link RelinkableCallSite} objects. Users of it (scripting
- * frameworks and language runtimes) have to create a linker using the
- * {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic
- * bootstrap methods to set the target of all the call sites in the code they
- * generate. Usual usage would be to create one class per language runtime to
- * contain one linker instance as:
+ * The linker for {@link RelinkableCallSite} objects. Users of Dynalink have to
+ * create a linker using the {@link DynamicLinkerFactory} and invoke its
+ * {@link #link(RelinkableCallSite)} method from the invokedynamic bootstrap
+ * methods to let it manage all the call sites they create. Usual usage would be
+ * to create one class per language runtime to contain one linker instance as:
+ * <pre>
*
- * <pre>
* class MyLanguageRuntime {
* private static final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker();
* private static final DynamicLinker dynamicLinker = createDynamicLinker();
@@ -116,7 +115,7 @@
* }
*
* public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) {
- * return dynamicLinker.link(new MonomorphicCallSite(CallSiteDescriptorFactory.create(lookup, name, type)));
+ * return dynamicLinker.link(new MonomorphicCallSite(new SimpleCallSiteDescriptor(lookup, name, type)));
* }
* }
* </pre>
@@ -148,8 +147,8 @@
*/
public final class DynamicLinker {
/**
- * A permission to invoke the {@link #getCurrentLinkRequest()} method. It is named
- * {@code "dynalink.getCurrentLinkRequest"}.
+ * A permission to invoke the {@link #getCurrentLinkRequest()} method. It is
+ * named {@code "dynalink.getCurrentLinkRequest"}.
*/
public static final RuntimePermission GET_CURRENT_LINK_REQUEST_PERMISSION = new RuntimePermission("dynalink.getCurrentLinkRequest");
@@ -202,8 +201,8 @@
}
/**
- * Returns the object representing the lower level linker services of this
- * class that are normally exposed to individual language-specific linkers.
+ * Returns the object representing the linker services of this class that
+ * are normally exposed to individual language-specific linkers.
* While as a user of this class you normally only care about the
* {@link #link(RelinkableCallSite)} method, in certain circumstances you
* might want to use the lower level services directly; either to lookup
@@ -275,11 +274,11 @@
}
/**
- * Returns a stack trace element describing the location of the call site
- * currently being linked on the current thread. The operation internally
- * creates a Throwable object and inspects its stack trace, so it's
- * potentially expensive. The recommended usage for it is in writing
- * diagnostics code.
+ * Returns a stack trace element describing the location of the
+ * {@code invokedynamic} call site currently being linked on the current
+ * thread. The operation is potentially expensive and is intended for use in
+ * diagnostics code. For "free-floating" call sites (not associated with an
+ * {@code invokedynamic} instruction), the result is not well-defined.
*
* @return a stack trace element describing the location of the call site
* currently being linked, or null if it is not invoked while a call
@@ -304,10 +303,12 @@
}
/**
- * Returns the currently processed link request, or null if the method is invoked outside of the linking process.
+ * Returns the currently processed link request, or null if the method is
+ * invoked outside of the linking process.
* @return the currently processed link request, or null.
- * @throws SecurityException if the calling code doesn't have the {@code "dynalink.getCurrentLinkRequest"}
- * runtime permission (available as {@link #GET_CURRENT_LINK_REQUEST_PERMISSION}).
+ * @throws SecurityException if the calling code doesn't have the
+ * {@code "dynalink.getCurrentLinkRequest"} runtime permission (available as
+ * {@link #GET_CURRENT_LINK_REQUEST_PERMISSION}).
*/
public static LinkRequest getCurrentLinkRequest() {
return LinkerServicesImpl.getCurrentLinkRequest();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java Mon Oct 19 08:45:29 2015 +0200
@@ -107,16 +107,19 @@
import jdk.internal.dynalink.support.TypeUtilities;
/**
- * A factory class for creating {@link DynamicLinker}s. The usual dynamic linker is a linker composed of all
- * {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any
- * guarding linkers automatically discovered as declared in
- * {@code /META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker} resources in the classpath (see
- * {@link ServiceLoader} for the description of this mechanism), and the standard fallback {@link BeansLinker}.
+ * A factory class for creating {@link DynamicLinker} objects. The usual dynamic
+ * linker is a linker composed of all {@link GuardingDynamicLinker} objects
+ * known and pre-created by the caller as well as any guarding linkers
+ * automatically discovered as declared in
+ * {@code /META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker}
+ * resources in the classpath (see {@link ServiceLoader} for the description of
+ * this mechanism), and the standard fallback {@link BeansLinker}.
* See {@link DynamicLinker} documentation for tips on how to use this class.
*/
public final class DynamicLinkerFactory {
/**
- * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}.
+ * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink
+ * threshold}.
*/
public static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8;
@@ -132,10 +135,21 @@
private MethodHandleTransformer internalObjectsFilter;
/**
- * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread
- * context class loader at the time of {@link #createLinker()} invocation will be used.
+ * Creates a new dynamic linker factory with default configuration. Upon
+ * creation, the factory can be configured using various {@code setXxx()}
+ * methods and used to create one or more dynamic linkers according to its
+ * current configuration using {@link #createLinker()}.
+ */
+ public DynamicLinkerFactory() {
+ }
+
+ /**
+ * Sets the class loader for automatic discovery of available linkers. If
+ * not set explicitly, then the thread context class loader of the thread
+ * invoking {@link #createLinker()} invocation will be used.
*
- * @param classLoader the class loader used for the autodiscovery of available linkers.
+ * @param classLoader the class loader used for the automatic discovery of
+ * available linkers.
*/
public void setClassLoader(final ClassLoader classLoader) {
this.classLoader = classLoader;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/GuardedInvocationFilter.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/GuardedInvocationFilter.java Mon Oct 19 08:45:29 2015 +0200
@@ -88,19 +88,28 @@
import jdk.internal.dynalink.linker.LinkerServices;
/**
- * Interface for objects that are used to transform one guarded invocation into another one. Typical usage is for
- * implementing {@link DynamicLinkerFactory#setPrelinkFilter(GuardedInvocationFilter) pre-link filters}.
+ * Interface for objects that are used to transform one guarded invocation into
+ * another one. Typical usage is for implementing
+ * {@link DynamicLinkerFactory#setPrelinkFilter(GuardedInvocationFilter)
+ * pre-link filters}.
*/
@FunctionalInterface
public interface GuardedInvocationFilter {
/**
- * Given a guarded invocation, return a potentially different guarded invocation.
- * @param inv the original guarded invocation. Null is never passed.
- * @param linkRequest the link request for which the invocation was generated (usually by some linker).
- * @param linkerServices the linker services that can be used during creation of a new invocation.
- * @return either the passed guarded invocation or a different one, with the difference usually determined based on
- * information in the link request and the differing invocation created with the assistance of the linker services.
- * Whether or not {@code null} is an accepted return value is dependent on the user of the filter.
+ * Given a guarded invocation, return either the same or potentially
+ * different guarded invocation.
+ * @param inv the original guarded invocation.
+ * @param linkRequest the link request for which the invocation was
+ * generated (usually by some linker).
+ * @param linkerServices the linker services that can be used during
+ * creation of a new invocation.
+ * @return either the passed guarded invocation or a different one, with
+ * the difference usually determined based on information in the link
+ * request and the differing invocation created with the assistance of the
+ * linker services. Whether or not {@code null} is an accepted return value
+ * is dependent on the user of the filter.
+ * @throws NullPointerException is allowed if any of the passed arguments
+ * is null.
*/
public GuardedInvocation filter(GuardedInvocation inv, LinkRequest linkRequest, LinkerServices linkerServices);
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/MonomorphicCallSite.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/MonomorphicCallSite.java Mon Oct 19 08:45:29 2015 +0200
@@ -88,9 +88,10 @@
import jdk.internal.dynalink.support.AbstractRelinkableCallSite;
/**
- * A relinkable call site that implements monomorphic inline caching strategy. After it linked a method, it will keep it
- * until either its guard evaluates to false, or its switchpoint is invalidated, at which time it will throw away the
- * previous linkage, and trigger relinking with its associated {@link DynamicLinker}.
+ * A relinkable call site that implements monomorphic inline caching strategy,
+ * only being linked to a single {@link GuardedInvocation}. If that invocation
+ * is invalidated, it will throw it away and ask its associated
+ * {@link DynamicLinker} to relink it.
*/
public class MonomorphicCallSite extends AbstractRelinkableCallSite {
/**
@@ -102,12 +103,12 @@
}
@Override
- public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relink) {
- setTarget(guardedInvocation.compose(relink));
+ public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) {
+ setTarget(guardedInvocation.compose(relinkAndInvoke));
}
@Override
- public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relink) {
- relink(guardedInvocation, relink);
+ public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) {
+ relink(guardedInvocation, relinkAndInvoke);
}
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/RelinkableCallSite.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/RelinkableCallSite.java Mon Oct 19 08:45:29 2015 +0200
@@ -85,23 +85,35 @@
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MutableCallSite;
-import java.lang.invoke.VolatileCallSite;
import jdk.internal.dynalink.linker.GuardedInvocation;
/**
- * Interface for relinkable call sites. Language runtimes wishing to use this framework must use subclasses of
- * {@link CallSite} that also implement this interface as their call sites. There is a readily usable
- * {@link MonomorphicCallSite} subclass that implements monomorphic inline caching strategy as well as a
- * {@link ChainedCallSite} that retains a chain of already linked method handles. The reason this is defined as an
- * interface instead of a concrete, albeit abstract class is that it allows independent implementations to choose
- * between {@link MutableCallSite} and {@link VolatileCallSite} as they see fit.
+ * Interface for call sites managed by a {@link DynamicLinker}. Users of
+ * Dynalink must use subclasses of {@link CallSite} that also implement this
+ * interface as their call site implementations. There is a readily usable
+ * {@link MonomorphicCallSite} subclass that implements monomorphic inline
+ * caching strategy as well as {@link ChainedCallSite} that implements a
+ * polymorphic inline caching strategy and retains a chain of previously linked
+ * method handles. A relinkable call site will be managed by a
+ * {@link DynamicLinker} object after being associated with it using its
+ * {@link DynamicLinker#link(RelinkableCallSite)} method.
*/
public interface RelinkableCallSite {
/**
- * Initializes the relinkable call site by setting a relink-and-invoke method handle. The call site
- * implementation is supposed to set this method handle as its target.
- * @param relinkAndInvoke a relink-and-invoke method handle supplied by the {@link DynamicLinker}.
+ * Invoked by dynamic linker to initialize the relinkable call site by
+ * setting a relink-and-invoke method handle. The call site implementation
+ * is supposed to set this method handle as its target using
+ * {@link CallSite#setTarget(MethodHandle)}. Relink-and-invoke is the
+ * initial method handle set by
+ * {@link DynamicLinker#link(RelinkableCallSite)} that will cause the call
+ * site to be relinked to an appropriate target on its first invocation
+ * based on its arguments, and that linked target will then be invoked
+ * (hence the name). This linking protocol effectively delays linking until
+ * the call site is invoked with actual arguments and thus ensures that
+ * linkers can make nuanced linking decisions based on those arguments and
+ * not just on the static method type of the call site.
+ * @param relinkAndInvoke a relink-and-invoke method handle supplied by
+ * Dynalink.
*/
public void initialize(MethodHandle relinkAndInvoke);
@@ -113,33 +125,52 @@
public CallSiteDescriptor getDescriptor();
/**
- * This method will be called by the dynamic linker every time the call site is normally relinked. It will be passed
- * a {@code GuardedInvocation} that the call site should incorporate into its target method handle. When this method
- * is called, the call site is allowed to keep other non-invalidated invocations around for implementation of
- * polymorphic inline caches and compose them with this invocation to form its final target.
+ * This method will be called by the dynamic linker every time the call site
+ * is relinked (but see
+ * {@link #resetAndRelink(GuardedInvocation, MethodHandle)} for an
+ * exception). It will be passed a {@code GuardedInvocation} that the call
+ * site should incorporate into its target method handle. When this method
+ * is called, the call site is allowed to keep other non-invalidated
+ * invocations around for implementation of polymorphic inline caches and
+ * compose them with this invocation to form its final target.
*
- * @param guardedInvocation the guarded invocation that the call site should incorporate into its target method
- * handle.
- * @param fallback the fallback method. This is a method matching the method type of the call site that is supplied
- * by the {@link DynamicLinker} to be used by this call site as a fallback when it can't invoke its target with the
- * passed arguments. The fallback method is such that when it's invoked, it'll try to discover the adequate target
- * for the invocation, subsequently invoke {@link #relink(GuardedInvocation, MethodHandle)} or
- * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally invoke the target.
+ * @param guardedInvocation the guarded invocation that the call site should
+ * incorporate into its target method handle.
+ * @param relinkAndInvoke a relink-and-invoke method handle. This is a
+ * method handle matching the method type of the call site that is supplied
+ * by the {@link DynamicLinker} as a callback. It should be used by this
+ * call site as the ultimate fallback when it can't invoke its target with
+ * the passed arguments. The fallback method is such that when it's invoked,
+ * it'll try to obtain an adequate target {@link GuardedInvocation} for the
+ * invocation, and subsequently invoke
+ * {@link #relink(GuardedInvocation, MethodHandle)} or
+ * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally
+ * invoke the target.
*/
- public void relink(GuardedInvocation guardedInvocation, MethodHandle fallback);
+ public void relink(GuardedInvocation guardedInvocation, MethodHandle relinkAndInvoke);
/**
- * This method will be called by the dynamic linker every time the call site is relinked and the linker wishes the
- * call site to throw away any prior linkage state. It will be passed a {@code GuardedInvocation} that the call site
- * should use to build its target method handle. When this method is called, the call site is discouraged from
- * keeping previous state around, and is supposed to only link the current invocation.
+ * This method will be called by the dynamic linker every time the call site
+ * is relinked <b>and</b> the linker wishes the call site to throw away any
+ * prior linkage state (that is how it differs from
+ * {@link #relink(GuardedInvocation, MethodHandle)}). It will be passed a
+ * {@code GuardedInvocation} that the call site should use to build its new
+ * target method handle. When this method is called, the call site is
+ * discouraged from keeping any previous state, and is supposed to only
+ * link the current invocation.
*
- * @param guardedInvocation the guarded invocation that the call site should use to build its target method handle.
- * @param fallback the fallback method. This is a method matching the method type of the call site that is supplied
- * by the {@link DynamicLinker} to be used by this call site as a fallback when it can't invoke its target with the
- * passed arguments. The fallback method is such that when it's invoked, it'll try to discover the adequate target
- * for the invocation, subsequently invoke {@link #relink(GuardedInvocation, MethodHandle)} or
- * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally invoke the target.
+ * @param guardedInvocation the guarded invocation that the call site should
+ * use to build its target method handle.
+ * @param relinkAndInvoke a relink-and-invoke method handle. This is a
+ * method handle matching the method type of the call site that is supplied
+ * by the {@link DynamicLinker} as a callback. It should be used by this
+ * call site as the ultimate fallback when it can't invoke its target with
+ * the passed arguments. The fallback method is such that when it's invoked,
+ * it'll try to obtain an adequate target {@link GuardedInvocation} for the
+ * invocation, and subsequently invoke
+ * {@link #relink(GuardedInvocation, MethodHandle)} or
+ * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}, and finally
+ * invoke the target.
*/
- public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle fallback);
+ public void resetAndRelink(GuardedInvocation guardedInvocation, MethodHandle relinkAndInvoke);
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/TypeConverterFactory.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/TypeConverterFactory.java Mon Oct 19 08:45:29 2015 +0200
@@ -382,7 +382,6 @@
if(next != null) {
cacheable = cacheable && next.isCacheable();
final GuardedInvocation conversionInvocation = next.getConversionInvocation();
- conversionInvocation.assertType(type);
last = conversionInvocation.compose(last);
}
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/BeansLinker.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/BeansLinker.java Mon Oct 19 08:45:29 2015 +0200
@@ -83,7 +83,7 @@
package jdk.internal.dynalink.beans;
-import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
import java.util.Collection;
import java.util.Collections;
import jdk.internal.dynalink.CallSiteDescriptor;
@@ -95,36 +95,59 @@
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
/**
- * A linker for POJOs. Normally used as the ultimate fallback linker by the {@link DynamicLinkerFactory} so it is given
- * the chance to link calls to all objects that no other language runtime recognizes. Specifically, this linker will:
+ * A linker for ordinary Java objects. Normally used as the ultimate fallback
+ * linker by the {@link DynamicLinkerFactory} so it is given the chance to link
+ * calls to all objects that no other linker recognized. Specifically, this
+ * linker will:
* <ul>
- * <li>expose all public methods of form {@code setXxx()}, {@code getXxx()}, and {@code isXxx()} as property setters and
- * getters for {@code dyn:setProp} and {@code dyn:getProp} operations;</li>
- * <li>expose all public methods for invocation through {@code dyn:callMethod} operation;</li>
- * <li>expose all public methods for retrieval for {@code dyn:getMethod} operation; the methods thus retrieved can then
- * be invoked using {@code dyn:call};</li>
- * <li>expose all public fields as properties, unless there are getters or setters for the properties of the same name;</li>
- * <li>expose {@code dyn:getLength}, {@code dyn:getElem} and {@code dyn:setElem} on native Java arrays, as well as
- * {@link java.util.List} and {@link java.util.Map} objects; ({@code dyn:getLength} works on any
+ * <li>expose all public methods of form {@code setXxx()}, {@code getXxx()},
+ * and {@code isXxx()} as property setters and getters for {@code dyn:setProp}
+ * and {@code dyn:getProp} operations;</li>
+ * <li>expose all public methods for invocation through {@code dyn:callMethod}
+ * operation;</li>
+ * <li>expose all public methods for retrieval for {@code dyn:getMethod}
+ * operation; the methods thus retrieved can then be invoked using
+ * {@code dyn:call};</li>
+ * <li>expose all public fields as properties, unless there are getters or
+ * setters for the properties of the same name;</li>
+ * <li>expose {@code dyn:getLength}, {@code dyn:getElem} and
+ * {@code dyn:setElem} on native Java arrays, as well as {@link java.util.List}
+ * and {@link java.util.Map} objects; ({@code dyn:getLength} works on any
* {@link java.util.Collection});</li>
* <li>expose a virtual property named {@code length} on Java arrays;</li>
- * <li>expose {@code dyn:new} on instances of {@link StaticClass} as calls to constructors, including those static class
- * objects that represent Java arrays (their constructors take a single {@code int} parameter representing the length of
- * the array to create);</li>
- * <li>expose static methods, fields, and properties of classes in a similar manner to how instance method, fields, and
- * properties are exposed, on {@link StaticClass} objects.</li>
- * <li>expose a virtual property named {@code static} on instances of {@link java.lang.Class} to access their
- * {@link StaticClass}.</li>
+ * <li>expose {@code dyn:new} on instances of {@link StaticClass} as calls to
+ * constructors, including those static class objects that represent Java arrays
+ * (their constructors take a single {@code int} parameter representing the
+ * length of the array to create);</li>
+ * <li>expose static methods, fields, and properties of classes in a similar
+ * manner to how instance method, fields, and properties are exposed, on
+ * {@link StaticClass} objects.</li>
+ * <li>expose a virtual property named {@code static} on instances of
+ * {@link java.lang.Class} to access their {@link StaticClass}.</li>
* </ul>
- * <p><strong>Overloaded method resolution</strong> is performed automatically for property setters, methods, and
- * constructors. Additionally, manual overloaded method selection is supported by having a call site specify a name for
- * a method that contains an explicit signature, i.e. {@code dyn:getMethod:parseInt(String,int)}. You can use
- * non-qualified class names in such signatures regardless of those classes' packages, they will match any class with
- * the same non-qualified name. You only have to use a fully qualified class name in case non-qualified class names
- * would cause selection ambiguity (that is extremely rare).</p>
- * <p><strong>Variable argument invocation</strong> is handled for both methods and constructors.</p>
- * <p>Currently, only public fields and methods are supported. Any Lookup objects passed in the
- * {@link LinkRequest}s are ignored and {@link MethodHandles#publicLookup()} is used instead.</p>
+ * <p><strong>Overloaded method resolution</strong> is performed automatically
+ * for property setters, methods, and constructors. Additionally, manual
+ * overloaded method selection is supported by having a call site specify a name
+ * for a method that contains an explicit signature, i.e.
+ * {@code dyn:getMethod:parseInt(String,int)}. You can use non-qualified class
+ * names in such signatures regardless of those classes' packages, they will
+ * match any class with the same non-qualified name. You only have to use a
+ * fully qualified class name in case non-qualified class names would cause
+ * selection ambiguity (that is extremely rare). Overloaded resolution for
+ * constructors is not automatic as there is no logical place to attach that
+ * functionality to but if a language wishes to provide this functionality, it
+ * can use {@link #getConstructorMethod(Class, String)} as a useful building
+ * block for it.</p>
+ * <p><strong>Variable argument invocation</strong> is handled for both methods
+ * and constructors.</p>
+ * <p><strong>Caller sensitive methods</strong> can be linked as long as they
+ * are otherwise public and link requests have call site descriptors carrying
+ * full-strength {@link Lookup} objects and not weakened lookups or the public
+ * lookup.</p>
+ * <p>The class also exposes various static methods for discovery of available
+ * property and method names on classes and class instances, as well as access
+ * to per-class linkers using the {@link #getLinkerForClass(Class)}
+ * method.</p>
*/
public class BeansLinker implements GuardingDynamicLinker {
private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<TypeBasedGuardingDynamicLinker>() {
@@ -140,15 +163,16 @@
};
/**
- * Creates a new POJO linker.
+ * Creates a new beans linker.
*/
public BeansLinker() {
}
/**
- * Returns a bean linker for a particular single class. Useful when you need to override or extend the behavior of
- * linking for some classes in your language runtime's linker, but still want to delegate to the default behavior in
- * some cases.
+ * Returns a bean linker for a particular single class. Useful when you need
+ * to override or extend the behavior of linking for some classes in your
+ * language runtime's linker, but still want to delegate to the default
+ * behavior in some cases.
* @param clazz the class
* @return a bean linker for that class
*/
@@ -157,9 +181,12 @@
}
/**
- * Returns true if the object is a Dynalink Java dynamic method.
+ * Returns true if the object is a Java dynamic method (e.g., one
+ * obtained through a {@code dyn:getMethod} call on a Java object or
+ * {@link StaticClass} or through
+ * {@link #getConstructorMethod(Class, String)}.
*
- * @param obj the object we want to test for being a dynamic method
+ * @param obj the object we want to test for being a Java dynamic method.
* @return true if it is a dynamic method, false otherwise.
*/
public static boolean isDynamicMethod(final Object obj) {
@@ -167,9 +194,10 @@
}
/**
- * Returns true if the object is a Dynalink Java constructor.
+ * Returns true if the object is a Java constructor (obtained through
+ * {@link #getConstructorMethod(Class, String)}}.
*
- * @param obj the object we want to test for being a constructor
+ * @param obj the object we want to test for being a Java constructor.
* @return true if it is a constructor, false otherwise.
*/
public static boolean isDynamicConstructor(final Object obj) {
@@ -177,10 +205,15 @@
}
/**
- * Return the dynamic method of constructor of the given class and the given signature.
+ * Return the dynamic method of constructor of the given class and the given
+ * signature. This method is useful for exposing a functionality for
+ * selecting an overloaded constructor based on an explicit signature, as
+ * this functionality is not otherwise exposed by Dynalink as
+ * {@link StaticClass} objects act as overloaded constructors without
+ * explicit signature selection.
* @param clazz the class
* @param signature full signature of the constructor
- * @return DynamicMethod for the constructor
+ * @return dynamic method for the constructor
*/
public static Object getConstructorMethod(final Class<?> clazz, final String signature) {
return StaticClassLinker.getConstructorMethod(clazz, signature);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/StaticClass.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/StaticClass.java Mon Oct 19 08:45:29 2015 +0200
@@ -87,12 +87,22 @@
import java.util.Objects;
/**
- * Object that represents the static facet of a class (its static methods, properties, and fields, as well as
- * construction of instances using "dyn:new"). Objects of this class are recognized by the {@link BeansLinker} as being
- * special, and operations on them will be linked against the represented class' static facet. The "class" synthetic
- * property is additionally recognized and returns the Java {@link Class} object, as per {@link #getRepresentedClass()}
- * method. Conversely, {@link Class} objects exposed through {@link BeansLinker} expose the "static" synthetic property
- * which returns an instance of this class.
+ * Object that represents the static aspect of a class (its static methods,
+ * properties, and fields, as well as construction of instances using
+ * {@code "dyn:new"} operation). Objects of this class are recognized by the
+ * {@link BeansLinker} as being special, and operations on them will be linked
+ * against the represented class' static aspect. The {@code "class"} synthetic
+ * property is additionally recognized and returns the Java {@link Class}
+ * object, as per {@link #getRepresentedClass()} method. Conversely,
+ * {@link Class} objects exposed through {@link BeansLinker} expose the
+ * {@code "static"} synthetic property which returns an instance of this class.
+ * Instances of this class act as namespaces for static members and as
+ * constructors for classes, much the same way as specifying a class name in
+ * Java does, except that in Dynalink they are expressed as actual objects
+ * exposing static methods and properties of classes. As a special case,
+ * {@code StaticClass} objects representing Java array types will act as
+ * constructors taking a single int argument and create an array of the
+ * specified size.
*/
public class StaticClass implements Serializable {
private static final ClassValue<StaticClass> staticClasses = new ClassValue<StaticClass>() {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/ConversionComparator.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/ConversionComparator.java Mon Oct 19 08:45:29 2015 +0200
@@ -85,11 +85,14 @@
/**
- * Optional interface to be implemented by {@link GuardingTypeConverterFactory} implementers. Language-specific
- * conversions can cause increased overloaded method resolution ambiguity, as many methods can become applicable because
- * of additional conversions. The static way of selecting the "most specific" method will fail more often, because there
- * will be multiple maximally specific method with unrelated signatures. In these cases, language runtimes can be asked
- * to resolve the ambiguity by expressing preferences for one conversion over the other.
+ * Optional interface to be implemented by {@link GuardingTypeConverterFactory}
+ * implementers. Language-specific conversions can cause increased overloaded
+ * method resolution ambiguity, as many methods can become applicable because of
+ * additional conversions. The static way of selecting the "most specific"
+ * method will fail more often, because there will be multiple maximally
+ * specific method with unrelated signatures. In these cases, language runtimes
+ * can be asked to resolve the ambiguity by expressing preferences for one
+ * conversion over the other.
*/
public interface ConversionComparator {
/**
@@ -105,12 +108,13 @@
}
/**
- * Determines which of the two target types is the preferred conversion target from a source type.
+ * Determines which of the two target types is the preferred conversion
+ * target from a source type.
* @param sourceType the source type.
* @param targetType1 one potential target type
* @param targetType2 another potential target type.
- * @return one of Comparison constants that establish which - if any - of the target types is preferred for the
- * conversion.
+ * @return one of Comparison constants that establish which - if any - of
+ * the target types is preferred for the conversion.
*/
public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2);
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedInvocation.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedInvocation.java Mon Oct 19 08:45:29 2015 +0200
@@ -83,24 +83,30 @@
package jdk.internal.dynalink.linker;
-import static jdk.nashorn.internal.lookup.Lookup.MH;
-
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.SwitchPoint;
-import java.lang.invoke.WrongMethodTypeException;
import java.util.List;
import java.util.Objects;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.support.Guards;
/**
- * Represents a conditionally valid method handle. It is an immutable triple of an invocation method handle, a guard
- * method handle that defines the applicability of the invocation handle, and a switch point that can be used for
- * external invalidation of the invocation handle. The invocation handle is suitable for invocation if the guard
- * handle returns true for its arguments, and as long as the switch point is not invalidated. Both the guard and the
- * switch point are optional; neither, one, or both can be present.
+ * Represents a conditionally valid method handle. Usually produced as a return
+ * value of
+ * {@link GuardingDynamicLinker#getGuardedInvocation(LinkRequest, LinkerServices)}
+ * and {@link GuardingTypeConverterFactory#convertToType(Class, Class)}. It is
+ * an immutable tuple of an invocation method handle, a guard method handle that
+ * defines the applicability of the invocation handle, zero or more switch
+ * points that can be used for external invalidation of the invocation handle,
+ * and an exception type that if thrown during an invocation of the method
+ * handle also invalidates it. The invocation handle is suitable for invocation
+ * if the guard handle returns true for its arguments, and as long as any of the
+ * switch points are not invalidated, and as long as it does not throw an
+ * exception of the designated type. The guard, the switch point, and the
+ * exception type are all optional (a guarded invocation having none of them is
+ * unconditionally valid).
*/
public class GuardedInvocation {
private final MethodHandle invocation;
@@ -109,9 +115,11 @@
private final SwitchPoint[] switchPoints;
/**
- * Creates a new guarded invocation. This invocation is unconditional as it has no invalidations.
+ * Creates a new unconditional guarded invocation. It is unconditional as it
+ * has no invalidations.
*
- * @param invocation the method handle representing the invocation. Must not be null.
+ * @param invocation the method handle representing the invocation. Must not
+ * be null.
* @throws NullPointerException if invocation is null.
*/
public GuardedInvocation(final MethodHandle invocation) {
@@ -119,12 +127,15 @@
}
/**
- * Creates a new guarded invocation.
+ * Creates a new guarded invocation, with a guard method handle.
*
- * @param invocation the method handle representing the invocation. Must not be null.
- * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
- * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null to represent
- * an unconditional invocation, although that is unusual.
+ * @param invocation the method handle representing the invocation. Must not
+ * be null.
+ * @param guard the method handle representing the guard. Must have be
+ * compatible with the {@code invocation} handle as per
+ * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}.
+ * For some useful guards, check out the {@link Guards} class. It can be
+ * null to represent an unconditional invocation.
* @throws NullPointerException if invocation is null.
*/
public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard) {
@@ -132,10 +143,14 @@
}
/**
- * Creates a new guarded invocation.
+ * Creates a new guarded invocation that can be invalidated by a switch
+ * point.
*
- * @param invocation the method handle representing the invocation. Must not be null.
- * @param switchPoint the optional switch point that can be used to invalidate this linkage.
+ * @param invocation the method handle representing the invocation. Must
+ * not be null.
+ * @param switchPoint the optional switch point that can be used to
+ * invalidate this linkage. It can be null. If it is null, this represents
+ * an unconditional invocation.
* @throws NullPointerException if invocation is null.
*/
public GuardedInvocation(final MethodHandle invocation, final SwitchPoint switchPoint) {
@@ -143,13 +158,19 @@
}
/**
- * Creates a new guarded invocation.
+ * Creates a new guarded invocation, with both a guard method handle and a
+ * switch point that can be used to invalidate it.
*
- * @param invocation the method handle representing the invocation. Must not be null.
- * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
- * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it
- * and the switch point are null, this represents an unconditional invocation, which is legal but unusual.
- * @param switchPoint the optional switch point that can be used to invalidate this linkage.
+ * @param invocation the method handle representing the invocation. Must
+ * not be null.
+ * @param guard the method handle representing the guard. Must have be
+ * compatible with the {@code invocation} handle as per
+ * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}.
+ * For some useful guards, check out the {@link Guards} class. It can be
+ * null. If both it and the switch point are null, this represents an
+ * unconditional invocation.
+ * @param switchPoint the optional switch point that can be used to
+ * invalidate this linkage.
* @throws NullPointerException if invocation is null.
*/
public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint switchPoint) {
@@ -157,15 +178,22 @@
}
/**
- * Creates a new guarded invocation.
+ * Creates a new guarded invocation, with a guard method handle, a
+ * switch point that can be used to invalidate it, and an exception that if
+ * thrown when invoked also invalidates it.
*
- * @param invocation the method handle representing the invocation. Must not be null.
- * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
- * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it
- * and the switch point are null, this represents an unconditional invocation, which is legal but unusual.
- * @param switchPoint the optional switch point that can be used to invalidate this linkage.
- * @param exception the optional exception type that is expected to be thrown by the invocation and that also
- * invalidates the linkage.
+ * @param invocation the method handle representing the invocation. Must not
+ * be null.
+ * @param guard the method handle representing the guard. Must have be
+ * compatible with the {@code invocation} handle as per
+ * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}.
+ * For some useful guards, check out the {@link Guards} class. It can be
+ * null. If it and the switch point and the exception are all null, this
+ * represents an unconditional invocation.
+ * @param switchPoint the optional switch point that can be used to
+ * invalidate this linkage.
+ * @param exception the optional exception type that is when thrown by the
+ * invocation also invalidates it.
* @throws NullPointerException if invocation is null.
*/
public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint switchPoint, final Class<? extends Throwable> exception) {
@@ -176,15 +204,22 @@
}
/**
- * Creates a new guarded invocation
+ * Creates a new guarded invocation, with a guard method handle, any number
+ * of switch points that can be used to invalidate it, and an exception that
+ * if thrown when invoked also invalidates it.
*
- * @param invocation the method handle representing the invocation. Must not be null.
- * @param guard the method handle representing the guard. Must have the same method type as the invocation, except
- * it must return boolean. For some useful guards, check out the {@link Guards} class. It can be null. If both it
- * and the switch point are null, this represents an unconditional invocation, which is legal but unusual.
- * @param switchPoints the optional switch points that can be used to invalidate this linkage.
- * @param exception the optional exception type that is expected to be thrown by the invocation and that also
- * invalidates the linkage.
+ * @param invocation the method handle representing the invocation. Must not
+ * be null.
+ * @param guard the method handle representing the guard. Must have be
+ * compatible with the {@code invocation} handle as per
+ * {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}.
+ * For some useful guards, check out the {@link Guards} class. It can be
+ * null. If it and the exception are both null, and no switch points were
+ * specified, this represents an unconditional invocation.
+ * @param switchPoints optional switch points that can be used to
+ * invalidate this linkage.
+ * @param exception the optional exception type that is when thrown by the
+ * invocation also invalidates it.
* @throws NullPointerException if invocation is null.
*/
public GuardedInvocation(final MethodHandle invocation, final MethodHandle guard, final SwitchPoint[] switchPoints, final Class<? extends Throwable> exception) {
@@ -213,26 +248,32 @@
}
/**
- * Returns the switch point that can be used to invalidate the invocation handle.
+ * Returns the switch points that can be used to invalidate the linkage of
+ * this invocation handle.
*
- * @return the switch point that can be used to invalidate the invocation handle. Can be null.
+ * @return the switch points that can be used to invalidate the linkage of
+ * this invocation handle. Can be null.
*/
public SwitchPoint[] getSwitchPoints() {
return switchPoints == null ? null : switchPoints.clone();
}
/**
- * Returns the exception type that if thrown should be used to invalidate the linkage.
+ * Returns the exception type that if thrown by the invocation should
+ * invalidate the linkage of this guarded invocation.
*
- * @return the exception type that if thrown should be used to invalidate the linkage. Can be null.
+ * @return the exception type that if thrown should be used to invalidate
+ * the linkage. Can be null.
*/
public Class<? extends Throwable> getException() {
return exception;
}
/**
- * Returns true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated.
- * @return true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated.
+ * Returns true if and only if this guarded invocation has at least one
+ * invalidated switch point.
+ * @return true if and only if this guarded invocation has at least one
+ * invalidated switch point.
*/
public boolean hasBeenInvalidated() {
if (switchPoints == null) {
@@ -247,20 +288,6 @@
}
/**
- * Asserts that the invocation is of the specified type, and the guard (if present) is of the specified type with a
- * boolean return type.
- *
- * @param type the asserted type
- * @throws WrongMethodTypeException if the invocation and the guard are not of the expected method type.
- */
- public void assertType(final MethodType type) {
- assertType(invocation, type);
- if (guard != null) {
- assertType(guard, type.changeReturnType(Boolean.TYPE));
- }
- }
-
- /**
* Creates a new guarded invocation with different methods, preserving the switch point.
*
* @param newInvocation the new invocation
@@ -272,9 +299,10 @@
}
/**
- * Add a switchpoint to this guarded invocation
- * @param newSwitchPoint new switchpoint, or null for nop
- * @return new guarded invocation with the extra switchpoint
+ * Create a new guarded invocation with an added switch point.
+ * @param newSwitchPoint new switch point. Can be null in which case this
+ * method return the current guarded invocation with no changes.
+ * @return a guarded invocation with the added switch point.
*/
public GuardedInvocation addSwitchPoint(final SwitchPoint newSwitchPoint) {
if (newSwitchPoint == null) {
@@ -301,9 +329,11 @@
}
/**
- * Changes the type of the invocation, as if {@link MethodHandle#asType(MethodType)} was applied to its invocation
- * and its guard, if it has one (with return type changed to boolean, and parameter count potentially truncated for
- * the guard). If the invocation already is of the required type, returns this object.
+ * Changes the type of the invocation, as if
+ * {@link MethodHandle#asType(MethodType)} was applied to its invocation
+ * and its guard, if it has one (with return type changed to boolean, and
+ * parameter count potentially truncated for the guard). If the invocation
+ * already is of the required type, returns this object.
* @param newType the new type of the invocation.
* @return a guarded invocation with the new type applied to it.
*/
@@ -312,9 +342,11 @@
}
/**
- * Changes the type of the invocation, as if {@link LinkerServices#asType(MethodHandle, MethodType)} was applied to
- * its invocation and its guard, if it has one (with return type changed to boolean, and parameter count potentially
- * truncated for the guard). If the invocation already is of the required type, returns this object.
+ * Changes the type of the invocation, as if
+ * {@link LinkerServices#asType(MethodHandle, MethodType)} was applied to
+ * its invocation and its guard, if it has one (with return type changed to
+ * boolean, and parameter count potentially truncated for the guard). If the
+ * invocation already is of the required type, returns this object.
* @param linkerServices the linker services to use for the conversion
* @param newType the new type of the invocation.
* @return a guarded invocation with the new type applied to it.
@@ -325,10 +357,13 @@
}
/**
- * Changes the type of the invocation, as if {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)} was
- * applied to its invocation and {@link LinkerServices#asType(MethodHandle, MethodType)} applied to its guard, if it
- * has one (with return type changed to boolean, and parameter count potentially truncated for the guard). If the
- * invocation doesn't change its type, returns this object.
+ * Changes the type of the invocation, as if
+ * {@link LinkerServices#asTypeLosslessReturn(MethodHandle, MethodType)} was
+ * applied to its invocation and
+ * {@link LinkerServices#asType(MethodHandle, MethodType)} applied to its
+ * guard, if it has one (with return type changed to boolean, and parameter
+ * count potentially truncated for the guard). If the invocation doesn't
+ * change its type, returns this object.
* @param linkerServices the linker services to use for the conversion
* @param newType the new type of the invocation.
* @return a guarded invocation with the new type applied to it.
@@ -339,9 +374,11 @@
}
/**
- * Changes the type of the invocation, as if {@link MethodHandle#asType(MethodType)} was applied to its invocation
- * and its guard, if it has one (with return type changed to boolean for guard). If the invocation already is of the
- * required type, returns this object.
+ * Changes the type of the invocation, as if
+ * {@link MethodHandle#asType(MethodType)} was applied to its invocation
+ * and its guard, if it has one (with return type changed to boolean for
+ * guard). If the invocation already is of the required type, returns this
+ * object.
* @param desc a call descriptor whose method type is adapted.
* @return a guarded invocation with the new type applied to it.
*/
@@ -350,7 +387,8 @@
}
/**
- * Applies argument filters to both the invocation and the guard (if there is one).
+ * Applies argument filters to both the invocation and the guard (if there
+ * is one) with {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}.
* @param pos the position of the first argument being filtered
* @param filters the argument filters
* @return a filtered invocation
@@ -361,7 +399,8 @@
}
/**
- * Makes an invocation that drops arguments in both the invocation and the guard (if there is one).
+ * Makes an invocation that drops arguments in both the invocation and the
+ * guard (if there is one) with {@link MethodHandles#dropArguments(MethodHandle, int, List)}.
* @param pos the position of the first argument being dropped
* @param valueTypes the types of the values being dropped
* @return an invocation that drops arguments
@@ -372,7 +411,8 @@
}
/**
- * Makes an invocation that drops arguments in both the invocation and the guard (if there is one).
+ * Makes an invocation that drops arguments in both the invocation and the
+ * guard (if there is one) with {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}.
* @param pos the position of the first argument being dropped
* @param valueTypes the types of the values being dropped
* @return an invocation that drops arguments
@@ -384,8 +424,11 @@
/**
- * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back.
- * @param fallback the fallback method handle in case switchpoint is invalidated or guard returns false.
+ * Composes the invocation, guard, switch points, and the exception into a
+ * composite method handle that knows how to fall back when the guard fails
+ * or the invocation is invalidated.
+ * @param fallback the fallback method handle for when a switch point is
+ * invalidated, a guard returns false, or invalidating exception is thrown.
* @return a composite method handle.
*/
public MethodHandle compose(final MethodHandle fallback) {
@@ -393,10 +436,15 @@
}
/**
- * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back.
- * @param switchpointFallback the fallback method handle in case switchpoint is invalidated.
- * @param guardFallback the fallback method handle in case guard returns false.
- * @param catchFallback the fallback method in case the exception handler triggers
+ * Composes the invocation, guard, switch points, and the exception into a
+ * composite method handle that knows how to fall back when the guard fails
+ * or the invocation is invalidated.
+ * @param switchpointFallback the fallback method handle in case a switch
+ * point is invalidated.
+ * @param guardFallback the fallback method handle in case guard returns
+ * false.
+ * @param catchFallback the fallback method in case the exception handler
+ * triggers.
* @return a composite method handle.
*/
public MethodHandle compose(final MethodHandle guardFallback, final MethodHandle switchpointFallback, final MethodHandle catchFallback) {
@@ -411,7 +459,7 @@
final MethodHandle catchGuarded =
exception == null ?
guarded :
- MH.catchException(
+ MethodHandles.catchException(
guarded,
exception,
MethodHandles.dropArguments(
@@ -430,10 +478,4 @@
return spGuarded;
}
-
- private static void assertType(final MethodHandle mh, final MethodType type) {
- if(!mh.type().equals(type)) {
- throw new WrongMethodTypeException("Expected type: " + type + " actual type: " + mh.type());
- }
- }
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedTypeConversion.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardedTypeConversion.java Mon Oct 19 08:45:29 2015 +0200
@@ -83,17 +83,27 @@
package jdk.internal.dynalink.linker;
+
/**
- * Guarded type conversion
+ * A tuple of a {@link GuardedInvocation} describing a conditional type
+ * conversion and a boolean flag indicating whether the result is allowed to
+ * be cached. While most type conversions are cacheable, some can have security
+ * implications. An example is converting e.g. function objects from the source
+ * language into implementations of Java functional interface objects, with
+ * adapter classes for those interfaces being created on the fly and being
+ * sensitive to the protection domain of their creator. Such converter
+ * invocation must be marked as non-cacheable so that Dynalink will know not to
+ * keep and reuse them in different contexts.
*/
public class GuardedTypeConversion {
private final GuardedInvocation conversionInvocation;
private final boolean cacheable;
/**
- * Constructor
- * @param conversionInvocation guarded invocation for this type conversion
- * @param cacheable is this invocation cacheable
+ * Creates a new guarded type conversion.
+ * @param conversionInvocation guarded invocation implementing this type
+ * conversion.
+ * @param cacheable true if this invocation is cacheable, false otherwise.
*/
public GuardedTypeConversion(final GuardedInvocation conversionInvocation, final boolean cacheable) {
this.conversionInvocation = conversionInvocation;
@@ -101,16 +111,18 @@
}
/**
- * Get the invocation
- * @return invocation
+ * Returns the invocation implementing the type conversion.
+ * @return the invocation implementing the type conversion.
*/
public GuardedInvocation getConversionInvocation() {
return conversionInvocation;
}
/**
- * Check if invocation is cacheable
- * @return true if cacheable, false otherwise
+ * Returns true if this conversion is allowed to be cached and reused by
+ * Dynalink.
+ * @return true if this conversion is allowed to be cached and reused by
+ * Dynalink.
*/
public boolean isCacheable() {
return cacheable;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingDynamicLinker.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingDynamicLinker.java Mon Oct 19 08:45:29 2015 +0200
@@ -99,14 +99,14 @@
* @return a guarded invocation with a method handle suitable for the arguments, as well as a guard condition that
* if fails should trigger relinking. Must return null if it can't resolve the invocation. If the returned
* invocation is unconditional (which is actually quite rare), the guard in the return value can be null. The
- * invocation can also have a switch point for asynchronous invalidation of the linkage, as well as a
+ * invocation can also have any number of switch points for asynchronous invalidation of the linkage, as well as a
* {@link Throwable} subclass that describes an expected exception condition that also triggers relinking (often it
* is faster to rely on an infrequent but expected {@link ClassCastException} than on an always evaluated
* {@code instanceof} guard). While the linker must produce an
* invocation with parameter types matching those in the call site descriptor of the link request, it should not try
* to match the return type expected at the call site except when it can do it with only the conversions that lose
* neither precision nor magnitude, see {@link LinkerServices#asTypeLosslessReturn(java.lang.invoke.MethodHandle,
- * java.lang.invoke.MethodType)}.
+ * java.lang.invoke.MethodType)} for further explanation.
* @throws Exception if the operation fails for whatever reason
*/
public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices)
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java Mon Oct 19 08:45:29 2015 +0200
@@ -83,14 +83,15 @@
package jdk.internal.dynalink.linker;
+import jdk.internal.dynalink.beans.BeansLinker;
import jdk.internal.dynalink.support.TypeUtilities;
/**
* Optional interface that can be implemented by {@link GuardingDynamicLinker} implementations to provide
* language-runtime specific implicit type conversion capabilities. Note that if you implement this interface, you will
* very likely want to implement {@link ConversionComparator} interface too, as your additional language-specific
- * conversions, in absence of a strategy for prioritizing these conversions, will cause more ambiguity in selecting the
- * correct overload when trying to link to an overloaded POJO method.
+ * conversions, in absence of a strategy for prioritizing these conversions, will cause more ambiguity for
+ * {@link BeansLinker} in selecting the correct overload when trying to link to an overloaded Java method.
*/
public interface GuardingTypeConverterFactory {
/**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkRequest.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkRequest.java Mon Oct 19 08:45:29 2015 +0200
@@ -99,15 +99,19 @@
public CallSiteDescriptor getCallSiteDescriptor();
/**
- * Returns the arguments for the invocation being linked. The returned array is a clone; modifications to it won't
- * affect the arguments in this request.
+ * Returns the arguments for the invocation being linked. The returned array
+ * must be a clone; modifications to it must not affect the arguments in
+ * this request.
*
* @return the arguments for the invocation being linked.
*/
public Object[] getArguments();
/**
- * Returns the 0th argument for the invocation being linked; this is typically the receiver object.
+ * Returns the first argument for the invocation being linked; this is
+ * typically the receiver object. This is a shorthand for
+ * {@code getArguments()[0]} that also avoids the cloning of the arguments
+ * array.
*
* @return the receiver object.
*/
@@ -117,8 +121,8 @@
* Returns true if the call site is considered unstable, that is, it has been relinked more times than was
* specified in {@link DynamicLinkerFactory#setUnstableRelinkThreshold(int)}. Linkers should use this as a
* hint to prefer producing linkage that is more stable (its guard fails less frequently), even if that assumption
- * causes a less effective version of an operation to be linked. This is just a hint, of course, and linkers are
- * free to ignore this property.
+ * causes a less effective version of an operation to be linked. This is just a hint, though, and linkers are
+ * allowed to ignore this property.
* @return true if the call site is considered unstable.
*/
public boolean isCallSiteUnstable();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkerServices.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkerServices.java Mon Oct 19 08:45:29 2015 +0200
@@ -185,7 +185,8 @@
/**
* Modifies the method handle so that any parameters that can receive potentially internal language runtime objects
* will have a filter added on them to prevent them from escaping, potentially by wrapping them.
- * It can also potentially add an unwrapping filter to the return value.
+ * It can also potentially add an unwrapping filter to the return value. Basically transforms the method
+ * handle using the transformer configured by {@link DynamicLinkerFactory#setInternalObjectsFilter(MethodHandleTransformer)}.
* @param target the target method handle
* @return a method handle with parameters and/or return type potentially filtered for wrapping and unwrapping.
*/
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodHandleTransformer.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodHandleTransformer.java Mon Oct 19 08:45:29 2015 +0200
@@ -88,6 +88,7 @@
/**
* A generic interface describing operations that transform method handles.
*/
+@FunctionalInterface
public interface MethodHandleTransformer {
/**
* Transforms a method handle.
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodTypeConversionStrategy.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodTypeConversionStrategy.java Mon Oct 19 08:45:29 2015 +0200
@@ -87,8 +87,10 @@
import java.lang.invoke.MethodType;
/**
- * Interface for objects representing a strategy for converting a method handle to a new type.
+ * Interface for objects representing a strategy for converting a method handle
+ * to a new type.
*/
+@FunctionalInterface
public interface MethodTypeConversionStrategy {
/**
* Converts a method handle to a new type.
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/TypeBasedGuardingDynamicLinker.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/TypeBasedGuardingDynamicLinker.java Mon Oct 19 08:45:29 2015 +0200
@@ -83,11 +83,14 @@
package jdk.internal.dynalink.linker;
+import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker;
+
/**
* A guarding dynamic linker that can determine whether it can link the call site solely based on the type of the first
- * argument at linking invocation time. (The first argument is usually the receiver class). Most language-specific
+ * argument at linking invocation time. (The first argument is usually the receiver). Most language-specific
* linkers will fall into this category, as they recognize their native objects as Java objects of classes implementing
- * a specific language-native interface or superclass. The linker mechanism can optimize the dispatch for these linkers.
+ * a specific language-native interface or superclass. The linker mechanism can optimize the dispatch for these linkers,
+ * see {@link CompositeTypeBasedGuardingDynamicLinker}.
*/
public interface TypeBasedGuardingDynamicLinker extends GuardingDynamicLinker {
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/package-info.java Mon Oct 19 08:45:29 2015 +0200
@@ -0,0 +1,130 @@
+/*
+ * 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 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.
+*/
+
+/**
+ * <p>
+ * Dynalink is a library for dynamic linking high-level operations on objects
+ * such as "read a property", "write a property", "invoke a function" and so on,
+ * expressed as {@link java.lang.invoke.CallSite call sites}. As such, it is
+ * closely related to, and relies on, the {@link java.lang.invoke} package.
+ * </p><p>
+ * While {@link java.lang.invoke} provides a JVM-level foundation for
+ * application-specific dynamic linking of methods, it does not provide a way to
+ * express higher level operations on objects, nor methods that implement them.
+ * These operations are the usual regimen of operations in object-oriented
+ * environments: property access, access of elements of collections, invocation
+ * of constructors, invocation of named methods (potentially with multiple
+ * dispatch, e.g. link- and run-time equivalents of Java overloaded method
+ * resolution). These are all functions that are normally desired in a language
+ * on the JVM. When a JVM language is statically typed and its type system
+ * matches that of the JVM, it can accomplish this with use of the usual
+ * invocation bytecodes ({@code INVOKEVIRTUAL} etc.) as well as field access
+ * bytecodes ({@code GETFIELD}, {@code PUTFIELD}). However, if the language is
+ * dynamic (hence, types of some expressions are not known at the time the
+ * program is compiled to bytecode), or its type system doesn't match closely
+ * that of the JVM, then it should use {@code invokedynamic} call sites and let
+ * Dynalink link those.
+ * </p><p>
+ * Dynalink lets programs have their operations on objects of unknown static
+ * types linked dynamically at run time. It also lets a language expose a linker
+ * for its own object model. Finally, it provides a default linker for ordinary
+ * Java objects. Two languages both exporting their linkers in the same JVM will
+ * even be able to cross-link their operations with each other if an object
+ * belonging to one language is passed to code from the other language.
+ * </p>
+ * <p>
+ * Languages that use Dynalink will create and configure a
+ * {@link jdk.internal.dynalink.DynamicLinkerFactory} and use it to create a
+ * {@link jdk.internal.dynalink.DynamicLinker}.
+ * The thus created dynamic linker will have to be used to link any
+ * {@link jdk.internal.dynalink.RelinkableCallSite}s they create, most often from a
+ * {@link java.lang.invoke} bootstrap method.
+ * </p>
+ * <p>
+ * Languages that wish to define and use their own linkers will also need to
+ * use the {@link jdk.internal.dynalink.linker} package.
+ * </p>
+ * @since 1.9
+ */
+@jdk.Exported
+package jdk.internal.dynalink;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/package.html Mon Oct 19 08:39:06 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +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.
--->
- <body>
- <p>
- Contains the main API for using the dynamic linking facilities. A
- scripting framework or a language runtime that does not define its own
- linker but only uses linkers available in the system will only need to
- use classes and interfaces from this package.
- </p>
- <p>
- Languages that wish to define and use their own linkers will also need to
- use the {@link jdk.internal.dynalink.linker} package.
- </p>
- </body>
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java Mon Oct 19 08:45:29 2015 +0200
@@ -89,10 +89,18 @@
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. For security
- * and performance reasons, subclasses must implement {@link #lookupEquals(AbstractCallSiteDescriptor)},
+ * 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 {
@@ -102,6 +110,15 @@
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) {
@@ -109,8 +126,8 @@
}
/**
- * Returns true if this call site descriptor is equal to the passed, non-null call site descriptor of the
- * same class.
+ * 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.
*/
@@ -134,20 +151,32 @@
}
/**
- * 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
- * {@link #getLookup()} (e.g. directly using the implementation) and then delegate to
+ * 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;
- }
- if(l1.lookupClass() != l2.lookupClass()) {
+ } else if (l1 == null || l2 == null) {
+ return false;
+ } else if(l1.lookupClass() != l2.lookupClass()) {
return false;
}
return l1.lookupModes() == l2.lookupModes();
@@ -164,14 +193,24 @@
}
/**
- * 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.
+ * 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.lookupClass().hashCode() + 31 * lookup.lookupModes();
+ return lookup != null ? lookup.lookupClass().hashCode() + 31 * lookup.lookupModes() : 0;
}
@Override
@@ -183,9 +222,11 @@
}
/**
- * Return a string representation of this call site descriptor's {@link Lookup} object. Typically will
- * return {@link Lookup#toString()}.
- * @return a string representation of this call site descriptor's {@link Lookup} object.
+ * 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();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/AbstractRelinkableCallSite.java Mon Oct 19 08:45:29 2015 +0200
@@ -83,20 +83,31 @@
package jdk.internal.dynalink.support;
+import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MutableCallSite;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.RelinkableCallSite;
+import jdk.internal.dynalink.linker.GuardedInvocation;
/**
- * A basic implementation of the {@link RelinkableCallSite} as a {@link MutableCallSite} subclass.
+ * A basic implementation of the {@link RelinkableCallSite} as a
+ * {@link MutableCallSite}. It carries a {@link CallSiteDescriptor} passed in
+ * the constructor and provides the correct implementation of the
+ * {@link #initialize(MethodHandle)} method. Subclasses must provide
+ * {@link #relink(GuardedInvocation, MethodHandle)} and
+ * {@link #resetAndRelink(GuardedInvocation, MethodHandle)}
+ * methods.
*/
public abstract class AbstractRelinkableCallSite extends MutableCallSite implements RelinkableCallSite {
private final CallSiteDescriptor descriptor;
/**
- * Creates a new relinkable call site.
- * @param descriptor the descriptor for this call site
+ * Creates a new abstract relinkable call site.
+ * @param descriptor the descriptor for this call site that will be returned
+ * from {@link #getDescriptor()}. The call site's {@link CallSite#type()}
+ * will be equal to descriptor's {@link CallSiteDescriptor#getMethodType()}.
+ * @throws NullPointerException if {@code descriptor} is null.
*/
protected AbstractRelinkableCallSite(final CallSiteDescriptor descriptor) {
super(descriptor.getMethodType());
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeGuardingDynamicLinker.java Mon Oct 19 08:45:29 2015 +0200
@@ -86,15 +86,16 @@
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
+import java.util.Objects;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.linker.LinkerServices;
/**
- * A {@link GuardingDynamicLinker} that delegates sequentially to a list of other guarding dynamic linkers. The first
- * value returned from a component linker other than null is returned. If no component linker returns an invocation,
- * null is returned.
+ * A {@link GuardingDynamicLinker} that delegates sequentially to a list of
+ * other guarding dynamic linkers in its
+ * {@link #getGuardedInvocation(LinkRequest, LinkerServices)}.
*/
public class CompositeGuardingDynamicLinker implements GuardingDynamicLinker, Serializable {
@@ -106,15 +107,27 @@
* Creates a new composite linker.
*
* @param linkers a list of component linkers.
+ * @throws NullPointerException if {@code linkers} or any of its elements
+ * are null.
*/
public CompositeGuardingDynamicLinker(final Iterable<? extends GuardingDynamicLinker> linkers) {
final List<GuardingDynamicLinker> l = new LinkedList<>();
for(final GuardingDynamicLinker linker: linkers) {
- l.add(linker);
+ l.add(Objects.requireNonNull(linker));
}
this.linkers = l.toArray(new GuardingDynamicLinker[l.size()]);
}
+ /**
+ * Delegates the call to its component linkers. The first non-null value
+ * returned from a component linker is returned. If no component linker
+ * returns a non-null invocation, null is returned.
+ * @param linkRequest the object describing the request for linking a
+ * particular invocation
+ * @param linkerServices linker services
+ * @return the first non-null return value from a component linker, or null
+ * if none of the components returned a non-null.
+ */
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
throws Exception {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/CompositeTypeBasedGuardingDynamicLinker.java Mon Oct 19 08:45:29 2015 +0200
@@ -87,6 +87,7 @@
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Objects;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
import jdk.internal.dynalink.linker.LinkRequest;
@@ -94,10 +95,12 @@
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
/**
- * A composite type-based guarding dynamic linker. When a receiver of a not yet seen class is encountered, all linkers
- * are queried sequentially on their {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers
- * returning true are then bound to the class, and next time a receiver of same type is encountered, the linking is
- * delegated to those linkers only, speeding up dispatch.
+ * A composite type-based guarding dynamic linker. When a receiver of a not yet
+ * seen class is encountered, all linkers are queried sequentially on their
+ * {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers
+ * returning true are then bound to the class, and next time a receiver of same
+ * type is encountered, the linking is delegated to those linkers only, speeding
+ * up dispatch.
*/
public class CompositeTypeBasedGuardingDynamicLinker implements TypeBasedGuardingDynamicLinker, Serializable {
private static final long serialVersionUID = 1L;
@@ -149,15 +152,24 @@
* Creates a new composite type-based linker.
*
* @param linkers the component linkers
+ * @throws NullPointerException if {@code linkers} or any of its elements
+ * are null.
*/
public CompositeTypeBasedGuardingDynamicLinker(final Iterable<? extends TypeBasedGuardingDynamicLinker> linkers) {
final List<TypeBasedGuardingDynamicLinker> l = new LinkedList<>();
for(final TypeBasedGuardingDynamicLinker linker: linkers) {
- l.add(linker);
+ l.add(Objects.requireNonNull(linker));
}
this.classToLinker = new ClassToLinker(l.toArray(new TypeBasedGuardingDynamicLinker[l.size()]));
}
+ /**
+ * Returns true if any of the composite linkers return true from
+ * {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} for the type.
+ * @param type the type to link
+ * @return true if any of the composite linkers can link calls for the
+ * receiver type, false otherwise.
+ */
@Override
public boolean canLinkType(final Class<?> type) {
return !classToLinker.get(type).isEmpty();
@@ -180,17 +192,21 @@
}
/**
- * Optimizes a list of type-based linkers. If a group of adjacent linkers in the list all implement
- * {@link TypeBasedGuardingDynamicLinker}, they will be replaced with a single instance of
+ * Optimizes a list of type-based linkers. If a group of adjacent linkers in
+ * the list all implement {@link TypeBasedGuardingDynamicLinker}, they will
+ * be replaced with a single instance of
* {@link CompositeTypeBasedGuardingDynamicLinker} that contains them.
*
* @param linkers the list of linkers to optimize
* @return the optimized list
+ * @throws NullPointerException if {@code linkers} or any of its elements
+ * are null.
*/
public static List<GuardingDynamicLinker> optimize(final Iterable<? extends GuardingDynamicLinker> linkers) {
final List<GuardingDynamicLinker> llinkers = new LinkedList<>();
final List<TypeBasedGuardingDynamicLinker> tblinkers = new LinkedList<>();
for(final GuardingDynamicLinker linker: linkers) {
+ Objects.requireNonNull(linker);
if(linker instanceof TypeBasedGuardingDynamicLinker) {
tblinkers.add((TypeBasedGuardingDynamicLinker)linker);
} else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/DefaultInternalObjectFilter.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/DefaultInternalObjectFilter.java Mon Oct 19 08:45:29 2015 +0200
@@ -90,10 +90,15 @@
import jdk.internal.dynalink.linker.MethodHandleTransformer;
/**
- * Default implementation for a {@link DynamicLinkerFactory#setInternalObjectsFilter(MethodHandleTransformer)}.
- * Given a method handle of {@code Object(Object)} type for filtering parameter and another one of the same type for
- * filtering return values, applies them to passed method handles where their parameter types and/or return value types
- * are declared to be {@link Object}.
+ * Default implementation for a
+ * {@link DynamicLinkerFactory#setInternalObjectsFilter(MethodHandleTransformer)}
+ * that delegates to a pair of filtering method handles. Given a method handle
+ * of {@code Object(Object)} type for filtering parameter and another one of the
+ * same type for filtering return values, applies them to passed method handles,
+ * on those parameter types and/or return value types that are declared to be
+ * {@link Object}. Also handles {@link MethodHandle#isVarargsCollector() method
+ * handles that support variable arity calls} with a last {@code Object[]}
+ * parameter.
*/
public class DefaultInternalObjectFilter implements MethodHandleTransformer {
private static final MethodHandle FILTER_VARARGS = new Lookup(MethodHandles.lookup()).findStatic(
@@ -105,9 +110,12 @@
/**
* Creates a new filter.
- * @param parameterFilter the filter for method parameters. Must be of type {@code Object(Object)}, or null.
- * @param returnFilter the filter for return values. Must be of type {@code Object(Object)}, or null.
- * @throws IllegalArgumentException if one or both filters are not of the expected type.
+ * @param parameterFilter the filter for method parameters. Must be of type
+ * {@code Object(Object)}, or {@code null}.
+ * @param returnFilter the filter for return values. Must be of type
+ * {@code Object(Object)}, or {@code null}.
+ * @throws IllegalArgumentException if one or both filters are not of the
+ * expected type.
*/
public DefaultInternalObjectFilter(final MethodHandle parameterFilter, final MethodHandle returnFilter) {
this.parameterFilter = checkHandle(parameterFilter, "parameterFilter");
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/Lookup.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/Lookup.java Mon Oct 19 08:45:29 2015 +0200
@@ -91,14 +91,17 @@
import java.lang.reflect.Method;
/**
- * A wrapper around MethodHandles.Lookup that masks checked exceptions in those cases when you're looking up methods
- * within your own codebase (therefore it is an error if they are not present).
+ * A wrapper around {@link java.lang.invoke.MethodHandles.Lookup} that masks
+ * checked exceptions. It is useful in those cases when you're looking up
+ * methods within your own codebase (therefore it is an error if they are not
+ * present).
*/
public class Lookup {
private final MethodHandles.Lookup lookup;
/**
- * Creates a new instance, bound to an instance of {@link java.lang.invoke.MethodHandles.Lookup}.
+ * Creates a new instance, bound to an instance of
+ * {@link java.lang.invoke.MethodHandles.Lookup}.
*
* @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} it delegates to.
*/
@@ -112,23 +115,27 @@
public static final Lookup PUBLIC = new Lookup(MethodHandles.publicLookup());
/**
- * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered
- * {@link IllegalAccessException} into an {@link IllegalAccessError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)},
+ * converting any encountered {@link IllegalAccessException} into an
+ * {@link IllegalAccessError}.
*
* @param m the method to unreflect
* @return the unreflected method handle.
+ * @throws IllegalAccessError if the method is inaccessible.
*/
public MethodHandle unreflect(final Method m) {
return unreflect(lookup, m);
}
/**
- * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered
- * {@link IllegalAccessException} into an {@link IllegalAccessError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)},
+ * converting any encountered {@link IllegalAccessException} into an
+ * {@link IllegalAccessError}.
*
* @param lookup the lookup used to unreflect
* @param m the method to unreflect
* @return the unreflected method handle.
+ * @throws IllegalAccessError if the method is inaccessible.
*/
public static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) {
try {
@@ -141,11 +148,12 @@
}
/**
- * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)}, converting any encountered
- * {@link IllegalAccessException} into an {@link IllegalAccessError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)},
+ * converting any encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
*
* @param f the field for which a getter is unreflected
* @return the unreflected field getter handle.
+ * @throws IllegalAccessError if the getter is inaccessible.
*/
public MethodHandle unreflectGetter(final Field f) {
try {
@@ -158,9 +166,10 @@
}
/**
- * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}, converting any
- * encountered {@link IllegalAccessException} into an {@link IllegalAccessError} and {@link NoSuchFieldException}
- * into a {@link NoSuchFieldError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)},
+ * converting any encountered {@link IllegalAccessException} into an
+ * {@link IllegalAccessError} and {@link NoSuchFieldException} into a
+ * {@link NoSuchFieldError}.
*
* @param refc the class declaring the field
* @param name the name of the field
@@ -186,11 +195,14 @@
}
/**
- * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter(Field)}, converting any encountered
- * {@link IllegalAccessException} into an {@link IllegalAccessError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter(Field)},
+ * converting any encountered {@link IllegalAccessException} into an
+ * {@link IllegalAccessError}.
*
* @param f the field for which a setter is unreflected
* @return the unreflected field setter handle.
+ * @throws IllegalAccessError if the field is inaccessible.
+ * @throws NoSuchFieldError if the field does not exist.
*/
public MethodHandle unreflectSetter(final Field f) {
try {
@@ -203,23 +215,27 @@
}
/**
- * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any
- * encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)},
+ * converting any encountered {@link IllegalAccessException} into an
+ * {@link IllegalAccessError}.
*
* @param c the constructor to unreflect
* @return the unreflected constructor handle.
+ * @throws IllegalAccessError if the constructor is inaccessible.
*/
public MethodHandle unreflectConstructor(final Constructor<?> c) {
return unreflectConstructor(lookup, c);
}
/**
- * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any
- * encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)},
+ * converting any encountered {@link IllegalAccessException} into an
+ * {@link IllegalAccessError}.
*
* @param lookup the lookup used to unreflect
* @param c the constructor to unreflect
* @return the unreflected constructor handle.
+ * @throws IllegalAccessError if the constructor is inaccessible.
*/
public static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor<?> c) {
try {
@@ -232,8 +248,10 @@
}
/**
- * Performs a findSpecial on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an
- * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findSpecial(Class, String, MethodType, Class)}
+ * on the underlying lookup. Converts any encountered
+ * {@link IllegalAccessException} into an {@link IllegalAccessError} and
+ * {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
*
* @param declaringClass class declaring the method
* @param name the name of the method
@@ -263,8 +281,10 @@
}
/**
- * Performs a findStatic on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an
- * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findStatic(Class, String, MethodType)}
+ * on the underlying lookup. Converts any encountered
+ * {@link IllegalAccessException} into an {@link IllegalAccessError} and
+ * {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
*
* @param declaringClass class declaring the method
* @param name the name of the method
@@ -290,8 +310,10 @@
}
/**
- * Performs a findVirtual on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an
- * {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
+ * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findVirtual(Class, String, MethodType)}
+ * on the underlying lookup. Converts any encountered
+ * {@link IllegalAccessException} into an {@link IllegalAccessError} and
+ * {@link NoSuchMethodException} into a {@link NoSuchMethodError}.
*
* @param declaringClass class declaring the method
* @param name the name of the method
@@ -317,8 +339,9 @@
}
/**
- * Given a lookup, finds using {@link #findSpecial(Class, String, MethodType)} a method on that lookup's class.
- * Useful in classes' code for convenient linking to their own privates.
+ * Given a lookup, finds using {@link #findSpecial(Class, String, MethodType)}
+ * a method on that lookup's class. Useful in classes' code for convenient
+ * linking to their own privates.
* @param lookup the lookup for the class
* @param name the name of the method
* @param rtype the return type of the method
@@ -331,9 +354,11 @@
/**
- * Finds using {@link #findSpecial(Class, String, MethodType)} a method on that lookup's class. Useful in classes'
- * code for convenient linking to their own privates. It's easier to use than {@code findSpecial} in that you can
- * just list the parameter types, and don't have to specify lookup class.
+ * Finds using {@link #findSpecial(Class, String, MethodType)} a method on
+ * that lookup's class. Useful in classes' code for convenient linking to
+ * their own privates. It's also more convenient than {@code findSpecial}
+ * in that you can just list the parameter types, and don't have to specify
+ * lookup class.
* @param name the name of the method
* @param rtype the return type of the method
* @param ptypes the parameter types of the method
@@ -344,9 +369,11 @@
}
/**
- * Given a lookup, finds using {@link #findStatic(Class, String, MethodType)} a method on that lookup's class.
- * Useful in classes' code for convenient linking to their own privates. It's easier to use than {@code findStatic}
- * in that you can just list the parameter types, and don't have to specify lookup class.
+ * Given a lookup, finds using {@link #findStatic(Class, String, MethodType)}
+ * a method on that lookup's class. Useful in classes' code for convenient
+ * linking to their own privates. It's easier to use than {@code findStatic}
+ * in that you can just list the parameter types, and don't have to specify
+ * lookup class.
* @param lookup the lookup for the class
* @param name the name of the method
* @param rtype the return type of the method
@@ -358,9 +385,11 @@
}
/**
- * Finds using {@link #findStatic(Class, String, MethodType)} a method on that lookup's class. Useful in classes'
- * code for convenient linking to their own privates. It's easier to use than {@code findStatic} in that you can
- * just list the parameter types, and don't have to specify lookup class.
+ * Finds using {@link #findStatic(Class, String, MethodType)} a method on
+ * that lookup's class. Useful in classes' code for convenient linking to
+ * their own privates. It's easier to use than {@code findStatic}
+ * in that you can just list the parameter types, and don't have to specify
+ * lookup class.
* @param name the name of the method
* @param rtype the return type of the method
* @param ptypes the parameter types of the method
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/NameCodec.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/NameCodec.java Mon Oct 19 08:45:29 2015 +0200
@@ -87,18 +87,23 @@
/**
* Implements the name mangling and demangling as specified by John Rose's
- * <a href="https://blogs.oracle.com/jrose/entry/symbolic_freedom_in_the_vm" target="_blank">"Symbolic Freedom in the
- * VM"</a> article. It is recommended that implementers of languages on the JVM uniformly adopt this for symbolic
- * interoperability between languages. Normally, you would mangle the names as you're generating bytecode, and then
- * demangle them when you're creating {@link CallSiteDescriptor} objects. Note that you are expected to mangle
- * individual tokens, and not the whole name at the call site, i.e. the colon character normally separating the tokens
- * is never mangled. I.e. you wouldn't mangle {@code dyn:getProp:color} into {@code dyn\!getProp\!color}, but you would
- * mangle {@code dyn:getProp:color$} into {@code dyn:getProp:\=color\%} (only mangling the individual token containing
- * the symbol {@code color$}). {@link CallSiteDescriptor#tokenizeName(String)} (and by implication, all call site
- * descriptors it creates) will automatically perform demangling on the passed names. If you use this factory, or you
- * have your own way of creating call site descriptors, but you still delegate to this method of the default factory
- * (it is recommended that you do), then you have demangling handled for you already, and only need to ensure that you
- * mangle the names when you're emitting them in the bytecode.
+ * <a href="https://blogs.oracle.com/jrose/entry/symbolic_freedom_in_the_vm"
+ * target="_blank">"Symbolic Freedom in the VM"</a> article. It is recommended
+ * that implementers of languages on the JVM uniformly adopt this for symbolic
+ * interoperability between languages. Normally, you would mangle the names as
+ * you're generating bytecode, and then demangle them when you're creating
+ * {@link CallSiteDescriptor} objects. Note that you are expected to mangle
+ * individual tokens, and not the whole name at the call site, i.e. the colon
+ * character normally separating the tokens is never mangled. I.e. you wouldn't
+ * mangle {@code dyn:getProp:color} into {@code dyn\!getProp\!color}, but you
+ * would mangle {@code dyn:getProp:color$} into {@code dyn:getProp:\=color\%}
+ * (only mangling the individual token containing the symbol {@code color$}).
+ * {@link CallSiteDescriptor#tokenizeName(String)} already uses
+ * {@link #decode(String)} to perform demangling on the passed names. If you use
+ * that method when creating call site descriptors, (it is recommended that you
+ * do), then you have demangling handled for you already, and only need to
+ * ensure that you mangle the names using {@link #encode(String)} when you're
+ * emitting them in the bytecode.
*/
public class NameCodec {
private static final char ESCAPE_CHAR = '\\';
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/SimpleLinkRequest.java Mon Oct 19 08:39:06 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/SimpleLinkRequest.java Mon Oct 19 08:45:29 2015 +0200
@@ -98,8 +98,9 @@
/**
* Creates a new link request.
*
- * @param callSiteDescriptor the descriptor for the call site being linked
- * @param callSiteUnstable true if the call site being linked is considered unstable
+ * @param callSiteDescriptor the descriptor for the call site being linked.
+ * @param callSiteUnstable true if the call site being linked is considered
+ * unstable.
* @param arguments the arguments for the invocation
*/
public SimpleLinkRequest(final CallSiteDescriptor callSiteDescriptor, final boolean callSiteUnstable, final Object... arguments) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/package-info.java Mon Oct 19 08:45:29 2015 +0200
@@ -0,0 +1,91 @@
+/*
+ * 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 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.
+*/
+
+/**
+ * <p>Contains classes that make using Dynalink more convenient by providing
+ * basic implementations of some classes as well as various utilities.
+ * </p>
+ * @since 1.9
+ */
+@jdk.Exported
+package jdk.internal.dynalink.support;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/package.html Mon Oct 19 08:39:06 2015 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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.
--->
- <body>
- <p>
- Contains supporting classes for other packages. There is no guarantee that
- any of these classes or interfaces will not change in a manner that breaks
- backwards compatibility; they are not considered to be part of the public
- API.
- </p>
- </body>