() {
+ public Void run() {
+ javaSecurityAccess.doIntersectionPrivilege(action, eventAcc);
+ return null;
+ }
+ }, stack, srcAcc);
+ }
+ }
+
+ private static AccessControlContext getAccessControlContextFrom(Object src) {
+ return src instanceof Component ?
+ ((Component)src).getAccessControlContext() :
+ src instanceof MenuComponent ?
+ ((MenuComponent)src).getAccessControlContext() :
+ src instanceof TrayIcon ?
+ ((TrayIcon)src).getAccessControlContext() :
+ null;
+ }
+
+ /**
+ * Called from dispatchEvent() under a correct AccessControlContext
+ */
+ private void dispatchEventImpl(final AWTEvent event, final Object src) {
event.isPosted = true;
- Object src = event.getSource();
if (event instanceof ActiveEvent) {
// This could become the sole method of dispatching in time.
setCurrentEventAndMostRecentTimeImpl(event);
-
((ActiveEvent)event).dispatch();
} else if (src instanceof Component) {
((Component)src).dispatchEvent(event);
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/awt/LinearGradientPaint.java
--- a/jdk/src/share/classes/java/awt/LinearGradientPaint.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/awt/LinearGradientPaint.java Wed Jul 05 17:39:17 2017 +0200
@@ -57,8 +57,14 @@
*
*
*
- * The user may also select what action the {@code LinearGradientPaint}
- * should take when filling color outside the start and end points.
+ * The user may also select what action the {@code LinearGradientPaint} object
+ * takes when it is filling the space outside the start and end points by
+ * setting {@code CycleMethod} to either {@code REFLECTION} or {@code REPEAT}.
+ * The distances between any two colors in any of the reflected or repeated
+ * copies of the gradient are the same as the distance between those same two
+ * colors between the start and end points.
+ * Note that some minor variations in distances may occur due to sampling at
+ * the granularity of a pixel.
* If no cycle method is specified, {@code NO_CYCLE} will be chosen by
* default, which means the endpoint colors will be used to fill the
* remaining area.
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/awt/MenuComponent.java
--- a/jdk/src/share/classes/java/awt/MenuComponent.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/awt/MenuComponent.java Wed Jul 05 17:39:17 2017 +0200
@@ -33,6 +33,9 @@
import sun.awt.AWTAccessor;
import javax.accessibility.*;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+
/**
* The abstract class MenuComponent
is the superclass
* of all menu-related components. In this respect, the class
@@ -100,6 +103,23 @@
boolean newEventsOnly = false;
/*
+ * The menu's AccessControlContext.
+ */
+ private transient volatile AccessControlContext acc =
+ AccessController.getContext();
+
+ /*
+ * Returns the acc this menu component was constructed with.
+ */
+ final AccessControlContext getAccessControlContext() {
+ if (acc == null) {
+ throw new SecurityException(
+ "MenuComponent is missing AccessControlContext");
+ }
+ return acc;
+ }
+
+ /*
* Internal constants for serialization.
*/
final static String actionListenerK = Component.actionListenerK;
@@ -402,6 +422,9 @@
throws ClassNotFoundException, IOException, HeadlessException
{
GraphicsEnvironment.checkHeadless();
+
+ acc = AccessController.getContext();
+
s.defaultReadObject();
appContext = AppContext.getAppContext();
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/awt/MultipleGradientPaint.java
--- a/jdk/src/share/classes/java/awt/MultipleGradientPaint.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/awt/MultipleGradientPaint.java Wed Jul 05 17:39:17 2017 +0200
@@ -286,6 +286,10 @@
/**
* Returns a copy of the transform applied to the gradient.
*
+ *
+ * Note that if no transform is applied to the gradient
+ * when it is created, the identity transform is used.
+ *
* @return a copy of the transform applied to the gradient
*/
public final AffineTransform getTransform() {
@@ -293,10 +297,12 @@
}
/**
- * Returns the transparency mode for this Paint object.
+ * Returns the transparency mode for this {@code Paint} object.
*
- * @return an integer value representing the transparency mode for
- * this Paint object
+ * @return {@code OPAQUE} if all colors used by this
+ * {@code Paint} object are opaque,
+ * {@code TRANSLUCENT} if at least one of the
+ * colors used by this {@code Paint} object is not opaque.
* @see java.awt.Transparency
*/
public final int getTransparency() {
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/awt/RadialGradientPaint.java
--- a/jdk/src/share/classes/java/awt/RadialGradientPaint.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/awt/RadialGradientPaint.java Wed Jul 05 17:39:17 2017 +0200
@@ -71,8 +71,24 @@
*
*
*
- * The user may also select what action the {@code RadialGradientPaint}
- * should take when filling color outside the bounds of the circle's radius.
+ * The user may also select what action the {@code RadialGradientPaint} object
+ * takes when it is filling the space outside the circle's radius by
+ * setting {@code CycleMethod} to either {@code REFLECTION} or {@code REPEAT}.
+ * The gradient color proportions are equal for any particular line drawn
+ * from the focus point. The following figure shows that the distance AB
+ * is equal to the distance BC, and the distance AD is equal to the distance DE.
+ *
+ *
+ *
+ * If the gradient and graphics rendering transforms are uniformly scaled and
+ * the user sets the focus so that it coincides with the center of the circle,
+ * the gradient color proportions are equal for any line drawn from the center.
+ * The following figure shows the distances AB, BC, AD, and DE. They are all equal.
+ *
+ *
+ *
+ * Note that some minor variations in distances may occur due to sampling at
+ * the granularity of a pixel.
* If no cycle method is specified, {@code NO_CYCLE} will be chosen by
* default, which means the the last keyframe color will be used to fill the
* remaining area.
@@ -604,7 +620,7 @@
}
/**
- * Returns a copy of the end point of the gradient axis.
+ * Returns a copy of the focus point of the radial gradient.
*
* @return a {@code Point2D} object that is a copy of the focus point
*/
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/awt/TrayIcon.java
--- a/jdk/src/share/classes/java/awt/TrayIcon.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/awt/TrayIcon.java Wed Jul 05 17:39:17 2017 +0200
@@ -40,6 +40,8 @@
import sun.awt.SunToolkit;
import sun.awt.HeadlessToolkit;
import java.util.EventObject;
+import java.security.AccessControlContext;
+import java.security.AccessController;
/**
* A TrayIcon
object represents a tray icon that can be
@@ -90,6 +92,7 @@
* @author Anton Tarasov
*/
public class TrayIcon {
+
private Image image;
private String tooltip;
private PopupMenu popup;
@@ -103,6 +106,24 @@
transient MouseMotionListener mouseMotionListener;
transient ActionListener actionListener;
+ /*
+ * The tray icon's AccessControlContext.
+ *
+ * Unlike the acc in Component, this field is made final
+ * because TrayIcon is not serializable.
+ */
+ private final AccessControlContext acc = AccessController.getContext();
+
+ /*
+ * Returns the acc this tray icon was constructed with.
+ */
+ final AccessControlContext getAccessControlContext() {
+ if (acc == null) {
+ throw new SecurityException("TrayIcon is missing AccessControlContext");
+ }
+ return acc;
+ }
+
static {
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/awt/doc-files/RadialGradientPaint-3.png
Binary file jdk/src/share/classes/java/awt/doc-files/RadialGradientPaint-3.png has changed
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/awt/doc-files/RadialGradientPaint-4.png
Binary file jdk/src/share/classes/java/awt/doc-files/RadialGradientPaint-4.png has changed
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/awt/image/PackedColorModel.java
--- a/jdk/src/share/classes/java/awt/image/PackedColorModel.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/awt/image/PackedColorModel.java Wed Jul 05 17:39:17 2017 +0200
@@ -343,8 +343,13 @@
if (bitMasks.length != maskArray.length) {
return false;
}
+
+ /* compare 'effective' masks only, i.e. only part of the mask
+ * which fits the capacity of the transfer type.
+ */
+ int maxMask = (int)((1L << DataBuffer.getDataTypeSize(transferType)) - 1);
for (int i=0; i < bitMasks.length; i++) {
- if (bitMasks[i] != maskArray[i]) {
+ if ((maxMask & bitMasks[i]) != (maxMask & maskArray[i])) {
return false;
}
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java
--- a/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/beans/DefaultPersistenceDelegate.java Wed Jul 05 17:39:17 2017 +0200
@@ -35,7 +35,7 @@
* is the delegate used by default for classes about
* which no information is available. The DefaultPersistenceDelegate
* provides, version resilient, public API-based persistence for
- * classes that follow the JavaBeans conventions without any class specific
+ * classes that follow the JavaBeans™ conventions without any class specific
* configuration.
*
* The key assumptions are that the class has a nullary constructor
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/beans/DesignMode.java
--- a/jdk/src/share/classes/java/beans/DesignMode.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/beans/DesignMode.java Wed Jul 05 17:39:17 2017 +0200
@@ -31,7 +31,7 @@
* of java.beans.beancontext.BeanContext, in order to propagate to its nested hierarchy
* of java.beans.beancontext.BeanContextChild instances, the current "designTime" property.
*
- * The JavaBeans specification defines the notion of design time as is a
+ * The JavaBeans™ specification defines the notion of design time as is a
* mode in which JavaBeans instances should function during their composition
* and customization in a interactive design, composition or construction tool,
* as opposed to runtime when the JavaBean is part of an applet, application,
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/beans/IndexedPropertyChangeEvent.java
--- a/jdk/src/share/classes/java/beans/IndexedPropertyChangeEvent.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/beans/IndexedPropertyChangeEvent.java Wed Jul 05 17:39:17 2017 +0200
@@ -26,7 +26,7 @@
/**
* An "IndexedPropertyChange" event gets delivered whenever a component that
- * conforms to the JavaBeans specification (a "bean") changes a bound
+ * conforms to the JavaBeans™ specification (a "bean") changes a bound
* indexed property. This class is an extension of PropertyChangeEvent
* but contains the index of the property that has changed.
*
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/beans/Introspector.java
--- a/jdk/src/share/classes/java/beans/Introspector.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/beans/Introspector.java Wed Jul 05 17:39:17 2017 +0200
@@ -87,7 +87,7 @@
*
* For more information about introspection and design patterns, please
* consult the
- * JavaBeans specification .
+ * JavaBeans™ specification .
*/
public class Introspector {
@@ -1245,7 +1245,7 @@
try {
type = ClassFinder.findClass(name, type.getClassLoader());
// Each customizer should inherit java.awt.Component and implement java.beans.Customizer
- // according to the section 9.3 of JavaBeans specification
+ // according to the section 9.3 of JavaBeans™ specification
if (Component.class.isAssignableFrom(type) && Customizer.class.isAssignableFrom(type)) {
return type;
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/beans/VetoableChangeSupport.java
--- a/jdk/src/share/classes/java/beans/VetoableChangeSupport.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/beans/VetoableChangeSupport.java Wed Jul 05 17:39:17 2017 +0200
@@ -474,7 +474,7 @@
/**
* @serialField children Hashtable
* @serialField source Object
- * @serialField propertyChangeSupportSerializedDataVersion int
+ * @serialField vetoableChangeSupportSerializedDataVersion int
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("children", Hashtable.class),
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/beans/package.html
--- a/jdk/src/share/classes/java/beans/package.html Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/beans/package.html Wed Jul 05 17:39:17 2017 +0200
@@ -29,7 +29,7 @@
Contains classes related to developing
beans -- components
-based on the JavaBeansTM architecture.
+based on the JavaBeans™ architecture.
A few of the
classes are used by beans while they run in an application.
For example, the event classes are
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/CallSite.java
--- a/jdk/src/share/classes/java/dyn/CallSite.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,266 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package java.dyn;
-
-import sun.dyn.*;
-import sun.dyn.empty.Empty;
-import sun.misc.Unsafe;
-import java.util.Collection;
-
-/**
- * A {@code CallSite} is a holder for a variable {@link MethodHandle},
- * which is called its {@code target}.
- * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
- * all calls to the site's current target.
- * A {@code CallSite} may be associated with several {@code invokedynamic}
- * instructions, or it may be "free floating", associated with none.
- * In any case, it may be invoked through an associated method handle
- * called its {@linkplain #dynamicInvoker dynamic invoker}.
- *
- * {@code CallSite} is an abstract class which does not allow
- * direct subclassing by users. It has three immediate,
- * concrete subclasses that may be either instantiated or subclassed.
- *
- * If a mutable target is not required, an {@code invokedynamic} instruction
- * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
- * If a mutable target is required which has volatile variable semantics,
- * because updates to the target must be immediately and reliably witnessed by other threads,
- * a {@linkplain VolatileCallSite volatile call site} may be used.
- * Otherwise, if a mutable target is required,
- * a {@linkplain MutableCallSite mutable call site} may be used.
- *
- *
- * A non-constant call site may be relinked by changing its target.
- * The new target must have the same {@linkplain MethodHandle#type() type}
- * as the previous target.
- * Thus, though a call site can be relinked to a series of
- * successive targets, it cannot change its type.
- *
- * Here is a sample use of call sites and bootstrap methods which links every
- * dynamic call site to print its arguments:
-
-static void test() throws Throwable {
- // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
- InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
-}
-private static void printArgs(Object... args) {
- System.out.println(java.util.Arrays.deepToString(args));
-}
-private static final MethodHandle printArgs;
-static {
- MethodHandles.Lookup lookup = MethodHandles.lookup();
- Class thisClass = lookup.lookupClass(); // (who am I?)
- printArgs = lookup.findStatic(thisClass,
- "printArgs", MethodType.methodType(void.class, Object[].class));
-}
-private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
- // ignore caller and name, but match the type:
- return new ConstantCallSite(printArgs.asType(type));
-}
-
- * @author John Rose, JSR 292 EG
- */
-abstract
-public class CallSite {
- private static final Access IMPL_TOKEN = Access.getToken();
- static { MethodHandleImpl.initStatics(); }
-
- // Fields used only by the JVM. Do not use or change.
- private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
- private int vmindex; // supplied by the JVM (BCI within calling method)
-
- // The actual payload of this call site:
- /*package-private*/
- MethodHandle target;
-
- // Remove this field for PFD and delete deprecated methods:
- private MemberName calleeNameRemoveForPFD;
-
- /**
- * Make a blank call site object with the given method type.
- * An initial target method is supplied which will throw
- * an {@link IllegalStateException} if called.
- *
- * Before this {@code CallSite} object is returned from a bootstrap method,
- * it is usually provided with a more useful target method,
- * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
- * @throws NullPointerException if the proposed type is null
- */
- /*package-private*/
- CallSite(MethodType type) {
- target = MethodHandles.invokers(type).uninitializedCallSite();
- }
-
- /**
- * Make a blank call site object, possibly equipped with an initial target method handle.
- * @param target the method handle which will be the initial target of the call site
- * @throws NullPointerException if the proposed target is null
- */
- /*package-private*/
- CallSite(MethodHandle target) {
- target.type(); // null check
- this.target = target;
- }
-
- /**
- * Returns the type of this call site's target.
- * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
- * The {@code setTarget} method enforces this invariant by refusing any new target that does
- * not have the previous target's type.
- * @return the type of the current target, which is also the type of any future target
- */
- public MethodType type() {
- return target.type();
- }
-
- /** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
- * The parameters are JVM-specific.
- */
- void initializeFromJVM(String name,
- MethodType type,
- MemberName callerMethod,
- int callerBCI) {
- if (this.vmmethod != null) {
- // FIXME
- throw new InvokeDynamicBootstrapError("call site has already been linked to an invokedynamic instruction");
- }
- if (!this.type().equals(type)) {
- throw wrongTargetType(target, type);
- }
- this.vmindex = callerBCI;
- this.vmmethod = callerMethod;
- }
-
- /**
- * Returns the target method of the call site, according to the
- * behavior defined by this call site's specific class.
- * The immediate subclasses of {@code CallSite} document the
- * class-specific behaviors of this method.
- *
- * @return the current linkage state of the call site, its target method handle
- * @see ConstantCallSite
- * @see VolatileCallSite
- * @see #setTarget
- * @see ConstantCallSite#getTarget
- * @see MutableCallSite#getTarget
- * @see VolatileCallSite#getTarget
- */
- public abstract MethodHandle getTarget();
-
- /**
- * Updates the target method of this call site, according to the
- * behavior defined by this call site's specific class.
- * The immediate subclasses of {@code CallSite} document the
- * class-specific behaviors of this method.
- *
- * The type of the new target must be {@linkplain MethodType#equals equal to}
- * the type of the old target.
- *
- * @param newTarget the new target
- * @throws NullPointerException if the proposed new target is null
- * @throws WrongMethodTypeException if the proposed new target
- * has a method type that differs from the previous target
- * @see CallSite#getTarget
- * @see ConstantCallSite#setTarget
- * @see MutableCallSite#setTarget
- * @see VolatileCallSite#setTarget
- */
- public abstract void setTarget(MethodHandle newTarget);
-
- void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
- MethodType oldType = oldTarget.type();
- MethodType newType = newTarget.type(); // null check!
- if (!newType.equals(oldType))
- throw wrongTargetType(newTarget, oldType);
- }
-
- private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
- return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
- }
-
- /**
- * Produce a method handle equivalent to an invokedynamic instruction
- * which has been linked to this call site.
- *
- * This method is equivalent to the following code:
- *
- * MethodHandle getTarget, invoker, result;
- * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
- * invoker = MethodHandles.exactInvoker(this.type());
- * result = MethodHandles.foldArguments(invoker, getTarget)
- *
- *
- * @return a method handle which always invokes this call site's current target
- */
- public abstract MethodHandle dynamicInvoker();
-
- /*non-public*/ MethodHandle makeDynamicInvoker() {
- MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, GET_TARGET, this);
- MethodHandle invoker = MethodHandles.exactInvoker(this.type());
- return MethodHandles.foldArguments(invoker, getTarget);
- }
-
- private static final MethodHandle GET_TARGET;
- static {
- try {
- GET_TARGET = MethodHandles.Lookup.IMPL_LOOKUP.
- findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
- } catch (ReflectiveOperationException ignore) {
- throw new InternalError();
- }
- }
-
- /** This guy is rolled into the default target if a MethodType is supplied to the constructor. */
- /*package-private*/
- static Empty uninitializedCallSite() {
- throw new IllegalStateException("uninitialized call site");
- }
-
- // unsafe stuff:
- private static final Unsafe unsafe = Unsafe.getUnsafe();
- private static final long TARGET_OFFSET;
-
- static {
- try {
- TARGET_OFFSET = unsafe.objectFieldOffset(CallSite.class.getDeclaredField("target"));
- } catch (Exception ex) { throw new Error(ex); }
- }
-
- /*package-private*/
- void setTargetNormal(MethodHandle newTarget) {
- target = newTarget;
- //CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget);
- }
- /*package-private*/
- MethodHandle getTargetVolatile() {
- return (MethodHandle) unsafe.getObjectVolatile(this, TARGET_OFFSET);
- }
- /*package-private*/
- void setTargetVolatile(MethodHandle newTarget) {
- unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget);
- //CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/ClassValue.java
--- a/jdk/src/share/classes/java/dyn/ClassValue.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.
- */
-
-package java.dyn;
-
-import java.util.WeakHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.lang.reflect.UndeclaredThrowableException;
-
-/**
- * Lazily associate a computed value with (potentially) every type.
- * For example, if a dynamic language needs to construct a message dispatch
- * table for each class encountered at a message send call site,
- * it can use a {@code ClassValue} to cache information needed to
- * perform the message send quickly, for each class encountered.
- * @author John Rose, JSR 292 EG
- */
-public abstract class ClassValue {
- /**
- * Compute the given class's derived value for this {@code ClassValue}.
- *
- * This method will be invoked within the first thread that accesses
- * the value with the {@link #get get} method.
- *
- * Normally, this method is invoked at most once per class,
- * but it may be invoked again if there has been a call to
- * {@link #remove remove}.
- *
- * If this method throws an exception, the corresponding call to {@code get}
- * will terminate abnormally with that exception, and no class value will be recorded.
- *
- * @param type the type whose class value must be computed
- * @return the newly computed value associated with this {@code ClassValue}, for the given class or interface
- * @see #get
- * @see #remove
- */
- protected abstract T computeValue(Class> type);
-
- /**
- * Returns the value for the given class.
- * If no value has yet been computed, it is obtained by
- * an invocation of the {@link #computeValue computeValue} method.
- *
- * The actual installation of the value on the class
- * is performed atomically.
- * At that point, if several racing threads have
- * computed values, one is chosen, and returned to
- * all the racing threads.
- *
- * The {@code type} parameter is typically a class, but it may be any type,
- * such as an interface, a primitive type (like {@code int.class}), or {@code void.class}.
- *
- * In the absence of {@code remove} calls, a class value has a simple
- * state diagram: uninitialized and initialized.
- * When {@code remove} calls are made,
- * the rules for value observation are more complex.
- * See the documentation for {@link #remove remove} for more information.
- *
- * @param type the type whose class value must be computed or retrieved
- * @return the current value associated with this {@code ClassValue}, for the given class or interface
- * @throws NullPointerException if the argument is null
- * @see #remove
- * @see #computeValue
- */
- public T get(Class> type) {
- ClassValueMap map = getMap(type);
- if (map != null) {
- Object x = map.get(this);
- if (x != null) {
- return (T) map.unmaskNull(x);
- }
- }
- return setComputedValue(type);
- }
-
- /**
- * Removes the associated value for the given class.
- * If this value is subsequently {@linkplain #get read} for the same class,
- * its value will be reinitialized by invoking its {@link #computeValue computeValue} method.
- * This may result in an additional invocation of the
- * {@code computeValue computeValue} method for the given class.
- *
- * In order to explain the interaction between {@code get} and {@code remove} calls,
- * we must model the state transitions of a class value to take into account
- * the alternation between uninitialized and initialized states.
- * To do this, number these states sequentially from zero, and note that
- * uninitialized (or removed) states are numbered with even numbers,
- * while initialized (or re-initialized) states have odd numbers.
- *
- * When a thread {@code T} removes a class value in state {@code 2N},
- * nothing happens, since the class value is already uninitialized.
- * Otherwise, the state is advanced atomically to {@code 2N+1}.
- *
- * When a thread {@code T} queries a class value in state {@code 2N},
- * the thread first attempts to initialize the class value to state {@code 2N+1}
- * by invoking {@code computeValue} and installing the resulting value.
- *
- * When {@code T} attempts to install the newly computed value,
- * if the state is still at {@code 2N}, the class value will be initialized
- * with the computed value, advancing it to state {@code 2N+1}.
- *
- * Otherwise, whether the new state is even or odd,
- * {@code T} will discard the newly computed value
- * and retry the {@code get} operation.
- *
- * Discarding and retrying is an important proviso,
- * since otherwise {@code T} could potentially install
- * a disastrously stale value. For example:
- *
- * {@code T} calls {@code CV.get(C)} and sees state {@code 2N}
- * {@code T} quickly computes a time-dependent value {@code V0} and gets ready to install it
- * {@code T} is hit by an unlucky paging or scheduling event, and goes to sleep for a long time
- * ...meanwhile, {@code T2} also calls {@code CV.get(C)} and sees state {@code 2N}
- * {@code T2} quickly computes a similar time-dependent value {@code V1} and installs it on {@code CV.get(C)}
- * {@code T2} (or a third thread) then calls {@code CV.remove(C)}, undoing {@code T2}'s work
- * the previous actions of {@code T2} are repeated several times
- * also, the relevant computed values change over time: {@code V1}, {@code V2}, ...
- * ...meanwhile, {@code T} wakes up and attempts to install {@code V0}; this must fail
- *
- * We can assume in the above scenario that {@code CV.computeValue} uses locks to properly
- * observe the time-dependent states as it computes {@code V1}, etc.
- * This does not remove the threat of a stale value, since there is a window of time
- * between the return of {@code computeValue} in {@code T} and the installation
- * of the the new value. No user synchronization is possible during this time.
- *
- * @param type the type whose class value must be removed
- * @throws NullPointerException if the argument is null
- */
- public void remove(Class> type) {
- ClassValueMap map = getMap(type);
- if (map != null) {
- synchronized (map) {
- map.remove(this);
- }
- }
- }
-
- /// Implementation...
-
- // The hash code for this type is based on the identity of the object,
- // and is well-dispersed for power-of-two tables.
- /** @deprecated This override, which is implementation-specific, will be removed for PFD. */
- public final int hashCode() { return hashCode; }
- private final int hashCode = HASH_CODES.getAndAdd(0x61c88647);
- private static final AtomicInteger HASH_CODES = new AtomicInteger();
-
- private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
-
- /** Slow path for {@link #get}. */
- private T setComputedValue(Class> type) {
- ClassValueMap map = getMap(type);
- if (map == null) {
- map = initializeMap(type);
- }
- T value = computeValue(type);
- STORE_BARRIER.lazySet(0);
- // All stores pending from computeValue are completed.
- synchronized (map) {
- // Warm up the table with a null entry.
- map.preInitializeEntry(this);
- }
- STORE_BARRIER.lazySet(0);
- // All stores pending from table expansion are completed.
- synchronized (map) {
- value = (T) map.initializeEntry(this, value);
- // One might fear a possible race condition here
- // if the code for map.put has flushed the write
- // to map.table[*] before the writes to the Map.Entry
- // are done. This is not possible, since we have
- // warmed up the table with an empty entry.
- }
- return value;
- }
-
- // Replace this map by a per-class slot.
- private static final WeakHashMap, ClassValueMap> ROOT
- = new WeakHashMap, ClassValueMap>();
-
- private static ClassValueMap getMap(Class> type) {
- return ROOT.get(type);
- }
-
- private static ClassValueMap initializeMap(Class> type) {
- synchronized (ClassValue.class) {
- ClassValueMap map = ROOT.get(type);
- if (map == null)
- ROOT.put(type, map = new ClassValueMap());
- return map;
- }
- }
-
- static class ClassValueMap extends WeakHashMap {
- /** Make sure this table contains an Entry for the given key, even if it is empty. */
- void preInitializeEntry(ClassValue key) {
- if (!this.containsKey(key))
- this.put(key, null);
- }
- /** Make sure this table contains a non-empty Entry for the given key. */
- Object initializeEntry(ClassValue key, Object value) {
- Object prior = this.get(key);
- if (prior != null) {
- return unmaskNull(prior);
- }
- this.put(key, maskNull(value));
- return value;
- }
-
- Object maskNull(Object x) {
- return x == null ? this : x;
- }
- Object unmaskNull(Object x) {
- return x == this ? null : x;
- }
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/ConstantCallSite.java
--- a/jdk/src/share/classes/java/dyn/ConstantCallSite.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.
- */
-
-package java.dyn;
-
-/**
- * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
- * An {@code invokedynamic} instruction linked to a {@code ConstantCallSite} is permanently
- * bound to the call site's target.
- * @author John Rose, JSR 292 EG
- */
-public class ConstantCallSite extends CallSite {
- /**
- * Creates a call site with a permanent target.
- * @param target the target to be permanently associated with this call site
- * @throws NullPointerException if the proposed target is null
- */
- public ConstantCallSite(MethodHandle target) {
- super(target);
- }
-
- /**
- * Returns the target method of the call site, which behaves
- * like a {@code final} field of the {@code ConstantCallSite}.
- * That is, the the target is always the original value passed
- * to the constructor call which created this instance.
- *
- * @return the immutable linkage state of this call site, a constant method handle
- * @throws UnsupportedOperationException because this kind of call site cannot change its target
- */
- @Override public final MethodHandle getTarget() {
- return target;
- }
-
- /**
- * Always throws an {@link UnsupportedOperationException}.
- * This kind of call site cannot change its target.
- * @param ignore a new target proposed for the call site, which is ignored
- * @throws UnsupportedOperationException because this kind of call site cannot change its target
- */
- @Override public final void setTarget(MethodHandle ignore) {
- throw new UnsupportedOperationException("ConstantCallSite");
- }
-
- /**
- * Returns this call site's permanent target.
- * Since that target will never change, this is a correct implementation
- * of {@link CallSite#dynamicInvoker CallSite.dynamicInvoker}.
- * @return the immutable linkage state of this call site, a constant method handle
- */
- @Override
- public final MethodHandle dynamicInvoker() {
- return getTarget();
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/InvokeDynamic.java
--- a/jdk/src/share/classes/java/dyn/InvokeDynamic.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.
- */
-
-package java.dyn;
-
-/**
- * This is a place-holder class. Some HotSpot implementations need to see it.
- */
-final class InvokeDynamic {
- private InvokeDynamic() { throw new InternalError(); } // do not instantiate
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
--- a/jdk/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.
- */
-
-package java.dyn;
-
-/**
- * Thrown to indicate that an {@code invokedynamic} instruction has
- * failed to find its
- * {@linkplain BootstrapMethod bootstrap method},
- * or the bootstrap method has
- * failed to provide a
- * {@linkplain CallSite call site} with a {@linkplain CallSite#getTarget target}
- * of the correct {@linkplain MethodHandle#type method type}.
- *
- * @author John Rose, JSR 292 EG
- * @since 1.7
- */
-public class InvokeDynamicBootstrapError extends LinkageError {
- private static final long serialVersionUID = 292L;
-
- /**
- * Constructs an {@code InvokeDynamicBootstrapError} with no detail message.
- */
- public InvokeDynamicBootstrapError() {
- super();
- }
-
- /**
- * Constructs an {@code InvokeDynamicBootstrapError} with the specified
- * detail message.
- *
- * @param s the detail message.
- */
- public InvokeDynamicBootstrapError(String s) {
- super(s);
- }
-
- /**
- * Constructs a {@code InvokeDynamicBootstrapError} with the specified
- * detail message and cause.
- *
- * @param s the detail message.
- * @param cause the cause, may be {@code null}.
- */
- public InvokeDynamicBootstrapError(String s, Throwable cause) {
- super(s, cause);
- }
-
- /**
- * Constructs a {@code InvokeDynamicBootstrapError} with the specified
- * cause.
- *
- * @param cause the cause, may be {@code null}.
- */
- public InvokeDynamicBootstrapError(Throwable cause) {
- // cf. Throwable(Throwable cause) constructor.
- super(cause == null ? null : cause.toString());
- initCause(cause);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/Linkage.java
--- a/jdk/src/share/classes/java/dyn/Linkage.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.
- */
-
-package java.dyn;
-
-import java.dyn.MethodHandles.Lookup;
-import java.util.WeakHashMap;
-import sun.dyn.Access;
-import sun.dyn.MethodHandleImpl;
-import sun.dyn.util.VerifyAccess;
-import sun.reflect.Reflection;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-
-/**
- * CLASS WILL BE REMOVED FOR PFD:
- * Static routines for controlling invokedynamic behavior.
- * Replaced by non-static APIs.
- * @author John Rose, JSR 292 EG
- * @deprecated This class will be removed in the Public Final Draft.
- */
-public class Linkage {
- private static final Access IMPL_TOKEN = Access.getToken();
-
- private Linkage() {} // do not instantiate
-
- /**
- * METHOD WILL BE REMOVED FOR PFD:
- * Register a bootstrap method to use when linking dynamic call sites within
- * a given caller class.
- * @deprecated Use @{@link BootstrapMethod} annotations instead.
- */
- public static
- void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
- Class callc = Reflection.getCallerClass(2);
- if (callc != null && !VerifyAccess.isSamePackage(callerClass, callc))
- throw new IllegalArgumentException("cannot set bootstrap method on "+callerClass);
- MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
- }
-
- /**
- * METHOD WILL BE REMOVED FOR PFD:
- * Simplified version of {@code registerBootstrapMethod} for self-registration,
- * to be called from a static initializer.
- * @deprecated Use @{@link BootstrapMethod} annotations instead.
- */
- public static
- void registerBootstrapMethod(Class> runtime, String name) {
- Class callerClass = Reflection.getCallerClass(2);
- registerBootstrapMethodLookup(callerClass, runtime, name);
- }
-
- /**
- * METHOD WILL BE REMOVED FOR PFD:
- * Simplified version of {@code registerBootstrapMethod} for self-registration,
- * @deprecated Use @{@link BootstrapMethod} annotations instead.
- */
- public static
- void registerBootstrapMethod(String name) {
- Class callerClass = Reflection.getCallerClass(2);
- registerBootstrapMethodLookup(callerClass, callerClass, name);
- }
-
- private static
- void registerBootstrapMethodLookup(Class> callerClass, Class> runtime, String name) {
- Lookup lookup = new Lookup(IMPL_TOKEN, callerClass);
- MethodHandle bootstrapMethod;
- try {
- bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
- } catch (ReflectiveOperationException ex) {
- throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
- }
- MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
- }
-
- private static final MethodType BOOTSTRAP_METHOD_TYPE
- = MethodType.methodType(CallSite.class,
- Class.class, String.class, MethodType.class);
-
- /**
- * METHOD WILL BE REMOVED FOR PFD:
- * Invalidate all invokedynamic
call sites everywhere.
- * @deprecated Use {@linkplain MutableCallSite#setTarget call site target setting},
- * {@link MutableCallSite#syncAll call site update pushing},
- * and {@link SwitchPoint#guardWithTest target switching} instead.
- */
- public static
- Object invalidateAll() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * METHOD WILL BE REMOVED FOR PFD:
- * Invalidate all {@code invokedynamic} call sites in the bytecodes
- * of any methods of the given class.
- * @deprecated Use {@linkplain MutableCallSite#setTarget call site target setting},
- * {@link MutableCallSite#syncAll call site update pushing},
- * and {@link SwitchPoint#guardWithTest target switching} instead.
- */
- public static
- Object invalidateCallerClass(Class> callerClass) {
- throw new UnsupportedOperationException();
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/MethodHandle.java
--- a/jdk/src/share/classes/java/dyn/MethodHandle.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1009 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package java.dyn;
-
-//import sun.dyn.*;
-
-import sun.dyn.Access;
-import sun.dyn.MethodHandleImpl;
-
-import static java.dyn.MethodHandles.invokers; // package-private API
-import static sun.dyn.MemberName.newIllegalArgumentException; // utility
-
-/**
- * A method handle is a typed, directly executable reference to an underlying method,
- * constructor, field, or similar low-level operation, with optional
- * transformations of arguments or return values.
- * These transformations are quite general, and include such patterns as
- * {@linkplain #asType conversion},
- * {@linkplain #bindTo insertion},
- * {@linkplain java.dyn.MethodHandles#dropArguments deletion},
- * and {@linkplain java.dyn.MethodHandles#filterArguments substitution}.
- *
- * Note: The super-class of MethodHandle is Object.
- * Any other super-class visible in the Reference Implementation
- * will be removed before the Proposed Final Draft.
- * Also, the final version will not include any public or
- * protected constructors.
- *
- *
Method handle contents
- * Method handles are dynamically and strongly typed according to type descriptor.
- * They are not distinguished by the name or defining class of their underlying methods.
- * A method handle must be invoked using type descriptor which matches
- * the method handle's own {@linkplain #type method type}.
- *
- * Every method handle reports its type via the {@link #type type} accessor.
- * This type descriptor is a {@link java.dyn.MethodType MethodType} object,
- * whose structure is a series of classes, one of which is
- * the return type of the method (or {@code void.class} if none).
- *
- * A method handle's type controls the types of invocations it accepts,
- * and the kinds of transformations that apply to it.
- *
- * A method handle contains a pair of special invoker methods
- * called {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.
- * Both invoker methods provide direct access to the method handle's
- * underlying method, constructor, field, or other operation,
- * as modified by transformations of arguments and return values.
- * Both invokers accept calls which exactly match the method handle's own type.
- * The {@code invokeGeneric} invoker also accepts a range of other call types.
- *
- * Method handles are immutable and have no visible state.
- * Of course, they can be bound to underlying methods or data which exhibit state.
- * With respect to the Java Memory Model, any method handle will behave
- * as if all of its (internal) fields are final variables. This means that any method
- * handle made visible to the application will always be fully formed.
- * This is true even if the method handle is published through a shared
- * variable in a data race.
- *
- * Method handles cannot be subclassed by the user.
- * Implementations may (or may not) create internal subclasses of {@code MethodHandle}
- * which may be visible via the {@link java.lang.Object#getClass Object.getClass}
- * operation. The programmer should not draw conclusions about a method handle
- * from its specific class, as the method handle class hierarchy (if any)
- * may change from time to time or across implementations from different vendors.
- *
- *
Method handle compilation
- * A Java method call expression naming {@code invokeExact} or {@code invokeGeneric}
- * can invoke a method handle from Java source code.
- * From the viewpoint of source code, these methods can take any arguments
- * and their result can be cast to any return type.
- * Formally this is accomplished by giving the invoker methods
- * {@code Object} return types and variable-arity {@code Object} arguments,
- * but they have an additional quality called signature polymorphism
- * which connects this freedom of invocation directly to the JVM execution stack.
- *
- * As is usual with virtual methods, source-level calls to {@code invokeExact}
- * and {@code invokeGeneric} compile to an {@code invokevirtual} instruction.
- * More unusually, the compiler must record the actual argument types,
- * and may not perform method invocation conversions on the arguments.
- * Instead, it must push them on the stack according to their own unconverted types.
- * The method handle object itself is pushed on the stack before the arguments.
- * The compiler then calls the method handle with a type descriptor which
- * describes the argument and return types.
- *
- * To issue a complete type descriptor, the compiler must also determine
- * the return type. This is based on a cast on the method invocation expression,
- * if there is one, or else {@code Object} if the invocation is an expression
- * or else {@code void} if the invocation is a statement.
- * The cast may be to a primitive type (but not {@code void}).
- *
- * As a corner case, an uncasted {@code null} argument is given
- * a type descriptor of {@code java.lang.Void}.
- * The ambiguity with the type {@code Void} is harmless, since there are no references of type
- * {@code Void} except the null reference.
- *
- *
Method handle invocation
- * The first time a {@code invokevirtual} instruction is executed
- * it is linked, by symbolically resolving the names in the instruction
- * and verifying that the method call is statically legal.
- * This is true of calls to {@code invokeExact} and {@code invokeGeneric}.
- * In this case, the type descriptor emitted by the compiler is checked for
- * correct syntax and names it contains are resolved.
- * Thus, an {@code invokevirtual} instruction which invokes
- * a method handle will always link, as long
- * as the type descriptor is syntactically well-formed
- * and the types exist.
- *
- * When the {@code invokevirtual} is executed after linking,
- * the receiving method handle's type is first checked by the JVM
- * to ensure that it matches the descriptor.
- * If the type match fails, it means that the method which the
- * caller is invoking is not present on the individual
- * method handle being invoked.
- *
- * In the case of {@code invokeExact}, the type descriptor of the invocation
- * (after resolving symbolic type names) must exactly match the method type
- * of the receiving method handle.
- * In the case of {@code invokeGeneric}, the resolved type descriptor
- * must be a valid argument to the receiver's {@link #asType asType} method.
- * Thus, {@code invokeGeneric} is more permissive than {@code invokeExact}.
- *
- * After type matching, a call to {@code invokeExact} directly
- * and immediately invoke the method handle's underlying method
- * (or other behavior, as the case may be).
- *
- * A call to {@code invokeGeneric} works the same as a call to
- * {@code invokeExact}, if the type descriptor specified by the caller
- * exactly matches the method handle's own type.
- * If there is a type mismatch, {@code invokeGeneric} attempts
- * to adjust the type of the receiving method handle,
- * as if by a call to {@link #asType asType},
- * to obtain an exactly invokable method handle {@code M2}.
- * This allows a more powerful negotiation of method type
- * between caller and callee.
- *
- * (Note: The adjusted method handle {@code M2} is not directly observable,
- * and implementations are therefore not required to materialize it.)
- *
- *
Invocation checking
- * In typical programs, method handle type matching will usually succeed.
- * But if a match fails, the JVM will throw a {@link WrongMethodTypeException},
- * either directly (in the case of {@code invokeExact}) or indirectly as if
- * by a failed call to {@code asType} (in the case of {@code invokeGeneric}).
- *
- * Thus, a method type mismatch which might show up as a linkage error
- * in a statically typed program can show up as
- * a dynamic {@code WrongMethodTypeException}
- * in a program which uses method handles.
- *
- * Because method types contain "live" {@code Class} objects,
- * method type matching takes into account both types names and class loaders.
- * Thus, even if a method handle {@code M} is created in one
- * class loader {@code L1} and used in another {@code L2},
- * method handle calls are type-safe, because the caller's type
- * descriptor, as resolved in {@code L2},
- * is matched against the original callee method's type descriptor,
- * as resolved in {@code L1}.
- * The resolution in {@code L1} happens when {@code M} is created
- * and its type is assigned, while the resolution in {@code L2} happens
- * when the {@code invokevirtual} instruction is linked.
- *
- * Apart from the checking of type descriptors,
- * a method handle's capability to call its underlying method is unrestricted.
- * If a method handle is formed on a non-public method by a class
- * that has access to that method, the resulting handle can be used
- * in any place by any caller who receives a reference to it.
- *
- * Unlike with the Core Reflection API, where access is checked every time
- * a reflective method is invoked,
- * method handle access checking is performed
- * when the method handle is created .
- * In the case of {@code ldc} (see below), access checking is performed as part of linking
- * the constant pool entry underlying the constant method handle.
- *
- * Thus, handles to non-public methods, or to methods in non-public classes,
- * should generally be kept secret.
- * They should not be passed to untrusted code unless their use from
- * the untrusted code would be harmless.
- *
- *
Method handle creation
- * Java code can create a method handle that directly accesses
- * any method, constructor, or field that is accessible to that code.
- * This is done via a reflective, capability-based API called
- * {@link java.dyn.MethodHandles.Lookup MethodHandles.Lookup}
- * For example, a static method handle can be obtained
- * from {@link java.dyn.MethodHandles.Lookup#findStatic Lookup.findStatic}.
- * There are also conversion methods from Core Reflection API objects,
- * such as {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}.
- *
- * Like classes and strings, method handles that correspond to accessible
- * fields, methods, and constructors can also be represented directly
- * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
- * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
- * refers directly to an associated {@code CONSTANT_Methodref},
- * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
- * constant pool entry.
- * (For more details on method handle constants,
- * see the package summary .)
- *
- * Method handles produced by lookups or constant loads from methods or
- * constructors with the variable arity modifier bit ({@code 0x0080})
- * have a corresponding variable arity, as if they were defined with
- * the help of {@link #asVarargsCollector asVarargsCollector}.
- *
- * A method reference may refer either to a static or non-static method.
- * In the non-static case, the method handle type includes an explicit
- * receiver argument, prepended before any other arguments.
- * In the method handle's type, the initial receiver argument is typed
- * according to the class under which the method was initially requested.
- * (E.g., if a non-static method handle is obtained via {@code ldc},
- * the type of the receiver is the class named in the constant pool entry.)
- *
- * When a method handle to a virtual method is invoked, the method is
- * always looked up in the receiver (that is, the first argument).
- *
- * A non-virtual method handle to a specific virtual method implementation
- * can also be created. These do not perform virtual lookup based on
- * receiver type. Such a method handle simulates the effect of
- * an {@code invokespecial} instruction to the same method.
- *
- *
Usage examples
- * Here are some examples of usage:
- *
-Object x, y; String s; int i;
-MethodType mt; MethodHandle mh;
-MethodHandles.Lookup lookup = MethodHandles.lookup();
-// mt is (char,char)String
-mt = MethodType.methodType(String.class, char.class, char.class);
-mh = lookup.findVirtual(String.class, "replace", mt);
-s = (String) mh.invokeExact("daddy",'d','n');
-// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
-assert(s.equals("nanny"));
-// weakly typed invocation (using MHs.invoke)
-s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
-assert(s.equals("savvy"));
-// mt is (Object[])List
-mt = MethodType.methodType(java.util.List.class, Object[].class);
-mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
-assert(mh.isVarargsCollector());
-x = mh.invokeGeneric("one", "two");
-// invokeGeneric(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
-assert(x.equals(java.util.Arrays.asList("one","two")));
-// mt is (Object,Object,Object)Object
-mt = MethodType.genericMethodType(3);
-mh = mh.asType(mt);
-x = mh.invokeExact((Object)1, (Object)2, (Object)3);
-// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
-assert(x.equals(java.util.Arrays.asList(1,2,3)));
-// mt is { => int}
-mt = MethodType.methodType(int.class);
-mh = lookup.findVirtual(java.util.List.class, "size", mt);
-i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
-// invokeExact(Ljava/util/List;)I
-assert(i == 3);
-mt = MethodType.methodType(void.class, String.class);
-mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
-mh.invokeExact(System.out, "Hello, world.");
-// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
- *
- * Each of the above calls to {@code invokeExact} or {@code invokeGeneric}
- * generates a single invokevirtual instruction with
- * the type descriptor indicated in the following comment.
- *
- * Exceptions
- * The methods {@code invokeExact} and {@code invokeGeneric} are declared
- * to throw {@link java.lang.Throwable Throwable},
- * which is to say that there is no static restriction on what a method handle
- * can throw. Since the JVM does not distinguish between checked
- * and unchecked exceptions (other than by their class, of course),
- * there is no particular effect on bytecode shape from ascribing
- * checked exceptions to method handle invocations. But in Java source
- * code, methods which perform method handle calls must either explicitly
- * throw {@code java.lang.Throwable Throwable}, or else must catch all
- * throwables locally, rethrowing only those which are legal in the context,
- * and wrapping ones which are illegal.
- *
- * Signature polymorphism
- * The unusual compilation and linkage behavior of
- * {@code invokeExact} and {@code invokeGeneric}
- * is referenced by the term signature polymorphism .
- * A signature polymorphic method is one which can operate with
- * any of a wide range of call signatures and return types.
- * In order to make this work, both the Java compiler and the JVM must
- * give special treatment to signature polymorphic methods.
- *
- * In source code, a call to a signature polymorphic method will
- * compile, regardless of the requested type descriptor.
- * As usual, the Java compiler emits an {@code invokevirtual}
- * instruction with the given type descriptor against the named method.
- * The unusual part is that the type descriptor is derived from
- * the actual argument and return types, not from the method declaration.
- *
- * When the JVM processes bytecode containing signature polymorphic calls,
- * it will successfully link any such call, regardless of its type descriptor.
- * (In order to retain type safety, the JVM will guard such calls with suitable
- * dynamic type checks, as described elsewhere.)
- *
- * Bytecode generators, including the compiler back end, are required to emit
- * untransformed type descriptors for these methods.
- * Tools which determine symbolic linkage are required to accept such
- * untransformed descriptors, without reporting linkage errors.
- *
- * For the sake of tools (but not as a programming API), the signature polymorphic
- * methods are marked with a private yet standard annotation,
- * {@code @java.dyn.MethodHandle.PolymorphicSignature}.
- * The annotation's retention is {@code RUNTIME}, so that all tools can see it.
- *
- *
Formal rules for processing signature polymorphic methods
- *
- * The following methods (and no others) are signature polymorphic:
- *
- * {@link java.dyn.MethodHandle#invokeExact MethodHandle.invokeExact}
- * {@link java.dyn.MethodHandle#invokeGeneric MethodHandle.invokeGeneric}
- *
- *
- * A signature polymorphic method will be declared with the following properties:
- *
- * It must be native.
- * It must take a single varargs parameter of the form {@code Object...}.
- * It must produce a return value of type {@code Object}.
- * It must be contained within the {@code java.dyn} package.
- *
- * Because of these requirements, a signature polymorphic method is able to accept
- * any number and type of actual arguments, and can, with a cast, produce a value of any type.
- * However, the JVM will treat these declaration features as a documentation convention,
- * rather than a description of the actual structure of the methods as executed.
- *
- * When a call to a signature polymorphic method is compiled, the associated linkage information for
- * its arguments is not array of {@code Object} (as for other similar varargs methods)
- * but rather the erasure of the static types of all the arguments.
- *
- * In an argument position of a method invocation on a signature polymorphic method,
- * a null literal has type {@code java.lang.Void}, unless cast to a reference type.
- * (Note: This typing rule allows the null type to have its own encoding in linkage information
- * distinct from other types.
- *
- * The linkage information for the return type is derived from a context-dependent target typing convention.
- * The return type for a signature polymorphic method invocation is determined as follows:
- *
- * If the method invocation expression is an expression statement, the method is {@code void}.
- * Otherwise, if the method invocation expression is the immediate operand of a cast,
- * the return type is the erasure of the cast type.
- * Otherwise, the return type is the method's nominal return type, {@code Object}.
- *
- * (Programmers are encouraged to use explicit casts unless it is clear that a signature polymorphic
- * call will be used as a plain {@code Object} expression.)
- *
- * The linkage information for argument and return types is stored in the descriptor for the
- * compiled (bytecode) call site. As for any invocation instruction, the arguments and return value
- * will be passed directly on the JVM stack, in accordance with the descriptor,
- * and without implicit boxing or unboxing.
- *
- *
Interoperation between method handles and the Core Reflection API
- * Using factory methods in the {@link java.dyn.MethodHandles.Lookup Lookup} API,
- * any class member represented by a Core Reflection API object
- * can be converted to a behaviorally equivalent method handle.
- * For example, a reflective {@link java.lang.reflect.Method Method} can
- * be converted to a method handle using
- * {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect}.
- * The resulting method handles generally provide more direct and efficient
- * access to the underlying class members.
- *
- * As a special case,
- * when the Core Reflection API is used to view the signature polymorphic
- * methods {@code invokeExact} or {@code invokeGeneric} in this class,
- * they appear as single, non-polymorphic native methods.
- * Calls to these native methods do not result in method handle invocations.
- * Since {@code invokevirtual} instructions can natively
- * invoke method handles under any type descriptor, this reflective view conflicts
- * with the normal presentation via bytecodes.
- * Thus, these two native methods, as viewed by
- * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
- * are placeholders only.
- * If invoked via {@link java.lang.reflect.Method#invoke Method.invoke},
- * they will throw {@code UnsupportedOperationException}.
- *
- * In order to obtain an invoker method for a particular type descriptor,
- * use {@link java.dyn.MethodHandles#exactInvoker MethodHandles.exactInvoker},
- * or {@link java.dyn.MethodHandles#genericInvoker MethodHandles.genericInvoker}.
- * The {@link java.dyn.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
- * API is also able to return a method handle
- * to call {@code invokeExact} or {@code invokeGeneric},
- * for any specified type descriptor .
- *
- *
Interoperation between method handles and Java generics
- * A method handle can be obtained on a method, constructor, or field
- * which is declared with Java generic types.
- * As with the Core Reflection API, the type of the method handle
- * will constructed from the erasure of the source-level type.
- * When a method handle is invoked, the types of its arguments
- * or the return value cast type may be generic types or type instances.
- * If this occurs, the compiler will replace those
- * types by their erasures when when it constructs the type descriptor
- * for the {@code invokevirtual} instruction.
- *
- * Method handles do not represent
- * their function-like types in terms of Java parameterized (generic) types,
- * because there are three mismatches between function-like types and parameterized
- * Java types.
- *
- * Method types range over all possible arities,
- * from no arguments to up to 255 of arguments (a limit imposed by the JVM).
- * Generics are not variadic, and so cannot represent this.
- * Method types can specify arguments of primitive types,
- * which Java generic types cannot range over.
- * Higher order functions over method handles (combinators) are
- * often generic across a wide range of function types, including
- * those of multiple arities. It is impossible to represent such
- * genericity with a Java type parameter.
- *
- *
- * @see MethodType
- * @see MethodHandles
- * @author John Rose, JSR 292 EG
- */
-public abstract class MethodHandle
- // Note: This is an implementation inheritance hack, and will be removed
- // with a JVM change which moves the required hidden state onto this class.
- extends MethodHandleImpl
-{
- private static Access IMPL_TOKEN = Access.getToken();
- static { MethodHandleImpl.initStatics(); }
-
- // interface MethodHandle
- // { MethodType type(); public R invokeExact(A...) throws X; }
-
- /**
- * Internal marker interface which distinguishes (to the Java compiler)
- * those methods which are signature polymorphic .
- */
- @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
- @interface PolymorphicSignature { }
-
- private MethodType type;
-
- /**
- * Report the type of this method handle.
- * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
- * @return the method handle type
- */
- public MethodType type() {
- return type;
- }
-
- /**
- * CONSTRUCTOR WILL BE REMOVED FOR PFD:
- * Temporary constructor in early versions of the Reference Implementation.
- * Method handle inheritance (if any) will be contained completely within
- * the {@code java.dyn} package.
- */
- // The constructor for MethodHandle may only be called by privileged code.
- // Subclasses may be in other packages, but must possess
- // a token which they obtained from MH with a security check.
- // @param token non-null object which proves access permission
- // @param type type (permanently assigned) of the new method handle
- protected MethodHandle(Access token, MethodType type) {
- super(token);
- Access.check(token);
- this.type = type;
- }
-
- private void initType(MethodType type) {
- type.getClass(); // elicit NPE
- if (this.type != null) throw new InternalError();
- this.type = type;
- }
-
- static {
- // This hack allows the implementation package special access to
- // the internals of MethodHandle. In particular, the MTImpl has all sorts
- // of cached information useful to the implementation code.
- MethodHandleImpl.setMethodHandleFriend(IMPL_TOKEN, new MethodHandleImpl.MethodHandleFriend() {
- public void initType(MethodHandle mh, MethodType type) { mh.initType(type); }
- });
- }
-
- /**
- * Invoke the method handle, allowing any caller type descriptor, but requiring an exact type match.
- * The type descriptor at the call site of {@code invokeExact} must
- * exactly match this method handle's {@link #type type}.
- * No conversions are allowed on arguments or return values.
- *
- * When this method is observed via the Core Reflection API,
- * it will appear as a single native method, taking an object array and returning an object.
- * If this native method is invoked directly via
- * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
- * or indirectly via {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect},
- * it will throw an {@code UnsupportedOperationException}.
- * @throws WrongMethodTypeException if the target's type is not identical with the caller's type descriptor
- * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
- */
- public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
-
- /**
- * Invoke the method handle, allowing any caller type descriptor,
- * and optionally performing conversions on arguments and return values.
- *
- * If the call site type descriptor exactly matches this method handle's {@link #type type},
- * the call proceeds as if by {@link #invokeExact invokeExact}.
- *
- * Otherwise, the call proceeds as if this method handle were first
- * adjusted by calling {@link #asType asType} to adjust this method handle
- * to the required type, and then the call proceeds as if by
- * {@link #invokeExact invokeExact} on the adjusted method handle.
- *
- * There is no guarantee that the {@code asType} call is actually made.
- * If the JVM can predict the results of making the call, it may perform
- * adaptations directly on the caller's arguments,
- * and call the target method handle according to its own exact type.
- *
- * The type descriptor at the call site of {@code invokeGeneric} must
- * be a valid argument to the receivers {@code asType} method.
- * In particular, the caller must specify the same argument arity
- * as the callee's type,
- * if the callee is not a {@linkplain #asVarargsCollector variable arity collector}.
- *
- * When this method is observed via the Core Reflection API,
- * it will appear as a single native method, taking an object array and returning an object.
- * If this native method is invoked directly via
- * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
- * or indirectly via {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.unreflect},
- * it will throw an {@code UnsupportedOperationException}.
- * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's type descriptor
- * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
- * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
- */
- public final native @PolymorphicSignature Object invokeGeneric(Object... args) throws Throwable;
-
- /**
- * Perform a varargs invocation, passing the arguments in the given array
- * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
- * which mentions only the type {@code Object}, and whose arity is the length
- * of the argument array.
- *
- * Specifically, execution proceeds as if by the following steps,
- * although the methods are not guaranteed to be called if the JVM
- * can predict their effects.
- *
- * Determine the length of the argument array as {@code N}.
- * For a null reference, {@code N=0}.
- * Determine the generic type {@code TN} of {@code N} arguments as
- * as {@code TN=MethodType.genericMethodType(N)}.
- * Force the original target method handle {@code MH0} to the
- * required type, as {@code MH1 = MH0.asType(TN)}.
- * Spread the array into {@code N} separate arguments {@code A0, ...}.
- * Invoke the type-adjusted method handle on the unpacked arguments:
- * MH1.invokeExact(A0, ...).
- * Take the return value as an {@code Object} reference.
- *
- *
- * Because of the action of the {@code asType} step, the following argument
- * conversions are applied as necessary:
- *
- * reference casting
- * unboxing
- * widening primitive conversions
- *
- *
- * The result returned by the call is boxed if it is a primitive,
- * or forced to null if the return type is void.
- *
- * This call is equivalent to the following code:
- *
- * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
- * Object result = invoker.invokeExact(this, arguments);
- *
- *
- * Unlike the signature polymorphic methods {@code invokeExact} and {@code invokeGeneric},
- * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
- * It can therefore be used as a bridge between native or reflective code and method handles.
- *
- * @param arguments the arguments to pass to the target
- * @return the result returned by the target
- * @throws ClassCastException if an argument cannot be converted by reference casting
- * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
- * @throws Throwable anything thrown by the target method invocation
- * @see MethodHandles#spreadInvoker
- */
- public Object invokeWithArguments(Object... arguments) throws Throwable {
- int argc = arguments == null ? 0 : arguments.length;
- MethodType type = type();
- if (type.parameterCount() != argc) {
- // simulate invokeGeneric
- return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
- }
- if (argc <= 10) {
- MethodHandle invoker = invokers(type).genericInvoker();
- switch (argc) {
- case 0: return invoker.invokeExact(this);
- case 1: return invoker.invokeExact(this,
- arguments[0]);
- case 2: return invoker.invokeExact(this,
- arguments[0], arguments[1]);
- case 3: return invoker.invokeExact(this,
- arguments[0], arguments[1], arguments[2]);
- case 4: return invoker.invokeExact(this,
- arguments[0], arguments[1], arguments[2],
- arguments[3]);
- case 5: return invoker.invokeExact(this,
- arguments[0], arguments[1], arguments[2],
- arguments[3], arguments[4]);
- case 6: return invoker.invokeExact(this,
- arguments[0], arguments[1], arguments[2],
- arguments[3], arguments[4], arguments[5]);
- case 7: return invoker.invokeExact(this,
- arguments[0], arguments[1], arguments[2],
- arguments[3], arguments[4], arguments[5],
- arguments[6]);
- case 8: return invoker.invokeExact(this,
- arguments[0], arguments[1], arguments[2],
- arguments[3], arguments[4], arguments[5],
- arguments[6], arguments[7]);
- case 9: return invoker.invokeExact(this,
- arguments[0], arguments[1], arguments[2],
- arguments[3], arguments[4], arguments[5],
- arguments[6], arguments[7], arguments[8]);
- case 10: return invoker.invokeExact(this,
- arguments[0], arguments[1], arguments[2],
- arguments[3], arguments[4], arguments[5],
- arguments[6], arguments[7], arguments[8],
- arguments[9]);
- }
- }
-
- // more than ten arguments get boxed in a varargs list:
- MethodHandle invoker = invokers(type).spreadInvoker(0);
- return invoker.invokeExact(this, arguments);
- }
- /** Equivalent to {@code invokeWithArguments(arguments.toArray())}. */
- public Object invokeWithArguments(java.util.List> arguments) throws Throwable {
- return invokeWithArguments(arguments.toArray());
- }
-
- /**
- * Produce an adapter method handle which adapts the type of the
- * current method handle to a new type
- * The resulting method handle is guaranteed to report a type
- * which is equal to the desired new type.
- *
- * If the original type and new type are equal, returns {@code this}.
- *
- * This method provides the crucial behavioral difference between
- * {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}. The two methods
- * perform the same steps when the caller's type descriptor is identical
- * with the callee's, but when the types differ, {@link #invokeGeneric invokeGeneric}
- * also calls {@code asType} (or some internal equivalent) in order
- * to match up the caller's and callee's types.
- *
- * This method is equivalent to {@link MethodHandles#convertArguments convertArguments},
- * except for variable arity method handles produced by {@link #asVarargsCollector asVarargsCollector}.
- *
- * @param newType the expected type of the new method handle
- * @return a method handle which delegates to {@code this} after performing
- * any necessary argument conversions, and arranges for any
- * necessary return value conversions
- * @throws WrongMethodTypeException if the conversion cannot be made
- * @see MethodHandles#convertArguments
- */
- public MethodHandle asType(MethodType newType) {
- return MethodHandles.convertArguments(this, newType);
- }
-
- /**
- * Make an adapter which accepts a trailing array argument
- * and spreads its elements as positional arguments.
- * The new method handle adapts, as its target ,
- * the current method handle. The type of the adapter will be
- * the same as the type of the target, except that the final
- * {@code arrayLength} parameters of the target's type are replaced
- * by a single array parameter of type {@code arrayType}.
- *
- * If the array element type differs from any of the corresponding
- * argument types on the original target,
- * the original target is adapted to take the array elements directly,
- * as if by a call to {@link #asType asType}.
- *
- * When called, the adapter replaces a trailing array argument
- * by the array's elements, each as its own argument to the target.
- * (The order of the arguments is preserved.)
- * They are converted pairwise by casting and/or unboxing
- * to the types of the trailing parameters of the target.
- * Finally the target is called.
- * What the target eventually returns is returned unchanged by the adapter.
- *
- * Before calling the target, the adapter verifies that the array
- * contains exactly enough elements to provide a correct argument count
- * to the target method handle.
- * (The array may also be null when zero elements are required.)
- * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
- * @param arrayLength the number of arguments to spread from an incoming array argument
- * @return a new method handle which spreads its final array argument,
- * before calling the original method handle
- * @throws IllegalArgumentException if {@code arrayType} is not an array type
- * @throws IllegalArgumentException if target does not have at least
- * {@code arrayLength} parameter types
- * @throws WrongMethodTypeException if the implied {@code asType} call fails
- * @see #asCollector
- */
- public MethodHandle asSpreader(Class> arrayType, int arrayLength) {
- Class> arrayElement = arrayType.getComponentType();
- if (arrayElement == null) throw newIllegalArgumentException("not an array type");
- MethodType oldType = type();
- int nargs = oldType.parameterCount();
- if (nargs < arrayLength) throw newIllegalArgumentException("bad spread array length");
- int keepPosArgs = nargs - arrayLength;
- MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
- newType = newType.insertParameterTypes(keepPosArgs, arrayType);
- return MethodHandles.spreadArguments(this, newType);
- }
-
- /**
- * Make an adapter which accepts a given number of trailing
- * positional arguments and collects them into an array argument.
- * The new method handle adapts, as its target ,
- * the current method handle. The type of the adapter will be
- * the same as the type of the target, except that a single trailing
- * parameter (usually of type {@code arrayType}) is replaced by
- * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
- *
- * If the array type differs from the final argument type on the original target,
- * the original target is adapted to take the array type directly,
- * as if by a call to {@link #asType asType}.
- *
- * When called, the adapter replaces its trailing {@code arrayLength}
- * arguments by a single new array of type {@code arrayType}, whose elements
- * comprise (in order) the replaced arguments.
- * Finally the target is called.
- * What the target eventually returns is returned unchanged by the adapter.
- *
- * (The array may also be a shared constant when {@code arrayLength} is zero.)
- *
- * (Note: The {@code arrayType} is often identical to the last
- * parameter type of the original target.
- * It is an explicit argument for symmetry with {@code asSpreader}, and also
- * to allow the target to use a simple {@code Object} as its last parameter type.)
- *
- * In order to create a collecting adapter which is not restricted to a particular
- * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
- * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
- * @param arrayLength the number of arguments to collect into a new array argument
- * @return a new method handle which collects some trailing argument
- * into an array, before calling the original method handle
- * @throws IllegalArgumentException if {@code arrayType} is not an array type
- * or {@code arrayType} is not assignable to this method handle's trailing parameter type,
- * or {@code arrayLength} is not a legal array size
- * @throws WrongMethodTypeException if the implied {@code asType} call fails
- * @see #asSpreader
- * @see #asVarargsCollector
- */
- public MethodHandle asCollector(Class> arrayType, int arrayLength) {
- Class> arrayElement = arrayType.getComponentType();
- if (arrayElement == null) throw newIllegalArgumentException("not an array type");
- MethodType oldType = type();
- int nargs = oldType.parameterCount();
- if (nargs == 0) throw newIllegalArgumentException("no trailing argument");
- MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
- newType = newType.insertParameterTypes(nargs-1,
- java.util.Collections.>nCopies(arrayLength, arrayElement));
- return MethodHandles.collectArguments(this, newType);
- }
-
- /**
- * Make a variable arity adapter which is able to accept
- * any number of trailing positional arguments and collect them
- * into an array argument.
- *
- * The type and behavior of the adapter will be the same as
- * the type and behavior of the target, except that certain
- * {@code invokeGeneric} and {@code asType} requests can lead to
- * trailing positional arguments being collected into target's
- * trailing parameter.
- * Also, the last parameter type of the adapter will be
- * {@code arrayType}, even if the target has a different
- * last parameter type.
- *
- * When called with {@link #invokeExact invokeExact}, the adapter invokes
- * the target with no argument changes.
- * (Note: This behavior is different from a
- * {@linkplain #asCollector fixed arity collector},
- * since it accepts a whole array of indeterminate length,
- * rather than a fixed number of arguments.)
- *
- * When called with {@link #invokeGeneric invokeGeneric}, if the caller
- * type is the same as the adapter, the adapter invokes the target as with
- * {@code invokeExact}.
- * (This is the normal behavior for {@code invokeGeneric} when types match.)
- *
- * Otherwise, if the caller and adapter arity are the same, and the
- * trailing parameter type of the caller is a reference type identical to
- * or assignable to the trailing parameter type of the adapter,
- * the arguments and return values are converted pairwise,
- * as if by {@link MethodHandles#convertArguments convertArguments}.
- * (This is also normal behavior for {@code invokeGeneric} in such a case.)
- *
- * Otherwise, the arities differ, or the adapter's trailing parameter
- * type is not assignable from the corresponding caller type.
- * In this case, the adapter replaces all trailing arguments from
- * the original trailing argument position onward, by
- * a new array of type {@code arrayType}, whose elements
- * comprise (in order) the replaced arguments.
- *
- * The caller type must provides as least enough arguments,
- * and of the correct type, to satisfy the target's requirement for
- * positional arguments before the trailing array argument.
- * Thus, the caller must supply, at a minimum, {@code N-1} arguments,
- * where {@code N} is the arity of the target.
- * Also, there must exist conversions from the incoming arguments
- * to the target's arguments.
- * As with other uses of {@code invokeGeneric}, if these basic
- * requirements are not fulfilled, a {@code WrongMethodTypeException}
- * may be thrown.
- *
- * In all cases, what the target eventually returns is returned unchanged by the adapter.
- *
- * In the final case, it is exactly as if the target method handle were
- * temporarily adapted with a {@linkplain #asCollector fixed arity collector}
- * to the arity required by the caller type.
- * (As with {@code asCollector}, if the array length is zero,
- * a shared constant may be used instead of a new array.
- * If the implied call to {@code asCollector} would throw
- * an {@code IllegalArgumentException} or {@code WrongMethodTypeException},
- * the call to the variable arity adapter must throw
- * {@code WrongMethodTypeException}.)
- *
- * The behavior of {@link #asType asType} is also specialized for
- * variable arity adapters, to maintain the invariant that
- * {@code invokeGeneric} is always equivalent to an {@code asType}
- * call to adjust the target type, followed by {@code invokeExact}.
- * Therefore, a variable arity adapter responds
- * to an {@code asType} request by building a fixed arity collector,
- * if and only if the adapter and requested type differ either
- * in arity or trailing argument type.
- * The resulting fixed arity collector has its type further adjusted
- * (if necessary) to the requested type by pairwise conversion,
- * as if by another application of {@code asType}.
- *
- * When a method handle is obtained by executing an {@code ldc} instruction
- * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
- * as a variable arity method (with the modifier bit {@code 0x0080}),
- * the method handle will accept multiple arities, as if the method handle
- * constant were created by means of a call to {@code asVarargsCollector}.
- *
- * In order to create a collecting adapter which collects a predetermined
- * number of arguments, and whose type reflects this predetermined number,
- * use {@link #asCollector asCollector} instead.
- *
- * No method handle transformations produce new method handles with
- * variable arity, unless they are documented as doing so.
- * Therefore, besides {@code asVarargsCollector},
- * all methods in {@code MethodHandle} and {@code MethodHandles}
- * will return a method handle with fixed arity,
- * except in the cases where they are specified to return their original
- * operand (e.g., {@code asType} of the method handle's own type).
- *
- * Calling {@code asVarargsCollector} on a method handle which is already
- * of variable arity will produce a method handle with the same type and behavior.
- * It may (or may not) return the original variable arity method handle.
- *
- * Here is an example, of a list-making variable arity method handle:
- *
-MethodHandle asList = publicLookup()
- .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
- .asVarargsCollector(Object[].class);
-assertEquals("[]", asList.invokeGeneric().toString());
-assertEquals("[1]", asList.invokeGeneric(1).toString());
-assertEquals("[two, too]", asList.invokeGeneric("two", "too").toString());
-Object[] argv = { "three", "thee", "tee" };
-assertEquals("[three, thee, tee]", asList.invokeGeneric(argv).toString());
-List ls = (List) asList.invokeGeneric((Object)argv);
-assertEquals(1, ls.size());
-assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
- *
- *
- * Discussion:
- * These rules are designed as a dynamically-typed variation
- * of the Java rules for variable arity methods.
- * In both cases, callers to a variable arity method or method handle
- * can either pass zero or more positional arguments, or else pass
- * pre-collected arrays of any length. Users should be aware of the
- * special role of the final argument, and of the effect of a
- * type match on that final argument, which determines whether
- * or not a single trailing argument is interpreted as a whole
- * array or a single element of an array to be collected.
- * Note that the dynamic type of the trailing argument has no
- * effect on this decision, only a comparison between the static
- * type descriptor of the call site and the type of the method handle.)
- *
- * As a result of the previously stated rules, the variable arity behavior
- * of a method handle may be suppressed, by binding it to the exact invoker
- * of its own type, as follows:
- *
-MethodHandle vamh = publicLookup()
- .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
- .asVarargsCollector(Object[].class);
-MethodHandle mh = MethodHandles.exactInvoker(vamh.type()).bindTo(vamh);
-assert(vamh.type().equals(mh.type()));
-assertEquals("[1, 2, 3]", vamh.invokeGeneric(1,2,3).toString());
-boolean failed = false;
-try { mh.invokeGeneric(1,2,3); }
-catch (WrongMethodTypeException ex) { failed = true; }
-assert(failed);
- *
- * This transformation has no behavioral effect if the method handle is
- * not of variable arity.
- *
- * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
- * @return a new method handle which can collect any number of trailing arguments
- * into an array, before calling the original method handle
- * @throws IllegalArgumentException if {@code arrayType} is not an array type
- * or {@code arrayType} is not assignable to this method handle's trailing parameter type
- * @see #asCollector
- * @see #isVarargsCollector
- */
- public MethodHandle asVarargsCollector(Class> arrayType) {
- Class> arrayElement = arrayType.getComponentType();
- if (arrayElement == null) throw newIllegalArgumentException("not an array type");
- return MethodHandles.asVarargsCollector(this, arrayType);
- }
-
- /**
- * Determine if this method handle
- * supports {@linkplain #asVarargsCollector variable arity} calls.
- * Such method handles arise from the following sources:
- *
- * a call to {@linkplain #asVarargsCollector asVarargsCollector}
- * a call to a {@linkplain java.dyn.MethodHandles.Lookup lookup method}
- * which resolves to a variable arity Java method or constructor
- * an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
- * which resolves to a variable arity Java method or constructor
- *
- * @return true if this method handle accepts more than one arity of {@code invokeGeneric} calls
- * @see #asVarargsCollector
- */
- public boolean isVarargsCollector() {
- return false;
- }
-
- /**
- * Bind a value {@code x} to the first argument of a method handle, without invoking it.
- * The new method handle adapts, as its target ,
- * to the current method handle.
- * The type of the bound handle will be
- * the same as the type of the target, except that a single leading
- * reference parameter will be omitted.
- *
- * When called, the bound handle inserts the given value {@code x}
- * as a new leading argument to the target. The other arguments are
- * also passed unchanged.
- * What the target eventually returns is returned unchanged by the bound handle.
- *
- * The reference {@code x} must be convertible to the first parameter
- * type of the target.
- * @param x the value to bind to the first argument of the target
- * @return a new method handle which collects some trailing argument
- * into an array, before calling the original method handle
- * @throws IllegalArgumentException if the target does not have a
- * leading parameter type that is a reference type
- * @throws ClassCastException if {@code x} cannot be converted
- * to the leading parameter type of the target
- * @see MethodHandles#insertArguments
- */
- public MethodHandle bindTo(Object x) {
- return MethodHandles.insertArguments(this, 0, x);
- }
-
- /**
- * Returns a string representation of the method handle,
- * starting with the string {@code "MethodHandle"} and
- * ending with the string representation of the method handle's type.
- * In other words, this method returns a string equal to the value of:
- *
- * "MethodHandle" + type().toString()
- *
- *
- * Note: Future releases of this API may add further information
- * to the string representation.
- * Therefore, the present syntax should not be parsed by applications.
- *
- * @return a string representation of the method handle
- */
- @Override
- public String toString() {
- return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/MethodHandles.java
--- a/jdk/src/share/classes/java/dyn/MethodHandles.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2339 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package java.dyn;
-
-import java.lang.reflect.*;
-import sun.dyn.Access;
-import sun.dyn.MemberName;
-import sun.dyn.MethodHandleImpl;
-import sun.dyn.WrapperInstance;
-import sun.dyn.util.ValueConversions;
-import sun.dyn.util.VerifyAccess;
-import sun.dyn.util.Wrapper;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-import sun.dyn.Invokers;
-import sun.dyn.MethodTypeImpl;
-import sun.reflect.Reflection;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-import static sun.dyn.MemberName.newNoAccessException;
-
-/**
- * This class consists exclusively of static methods that operate on or return
- * method handles. They fall into several categories:
- *
- * Lookup methods which help create method handles for methods and fields.
- * Combinator methods, which combine or transform pre-existing method handles into new ones.
- * Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
- * Wrapper methods which can convert between method handles and other function-like "SAM types".
- *
- *
- * @author John Rose, JSR 292 EG
- */
-public class MethodHandles {
-
- private MethodHandles() { } // do not instantiate
-
- private static final Access IMPL_TOKEN = Access.getToken();
- private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(IMPL_TOKEN);
- static { MethodHandleImpl.initStatics(); }
- // See IMPL_LOOKUP below.
-
- //// Method handle creation from ordinary methods.
-
- /**
- * Return a {@link Lookup lookup object} on the caller,
- * which has the capability to access any method handle that the caller has access to,
- * including direct method handles to private fields and methods.
- * This lookup object is a capability which may be delegated to trusted agents.
- * Do not store it in place where untrusted code can access it.
- */
- public static Lookup lookup() {
- return new Lookup();
- }
-
- /**
- * Return a {@link Lookup lookup object} which is trusted minimally.
- * It can only be used to create method handles to
- * publicly accessible fields and methods.
- *
- * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
- * of this lookup object will be {@link java.lang.Object}.
- *
- * The lookup class can be changed to any other class {@code C} using an expression of the form
- * {@linkplain Lookup#in publicLookup().in(C.class)
}.
- * Since all classes have equal access to public names,
- * such a change would confer no new access rights.
- */
- public static Lookup publicLookup() {
- return Lookup.PUBLIC_LOOKUP;
- }
-
- /**
- * A lookup object is a factory for creating method handles,
- * when the creation requires access checking.
- * Method handles do not perform
- * access checks when they are called, but rather when they are created.
- * Therefore, method handle access
- * restrictions must be enforced when a method handle is created.
- * The caller class against which those restrictions are enforced
- * is known as the {@linkplain #lookupClass lookup class}.
- *
- * A lookup class which needs to create method handles will call
- * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
- * When the {@code Lookup} factory object is created, the identity of the lookup class is
- * determined, and securely stored in the {@code Lookup} object.
- * The lookup class (or its delegates) may then use factory methods
- * on the {@code Lookup} object to create method handles for access-checked members.
- * This includes all methods, constructors, and fields which are allowed to the lookup class,
- * even private ones.
- *
- * The factory methods on a {@code Lookup} object correspond to all major
- * use cases for methods, constructors, and fields.
- * Here is a summary of the correspondence between these factory methods and
- * the behavior the resulting method handles:
- *
- *
- * lookup expression member behavior
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}
- * FT f; (T) this.f;
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}
- * static FT f; (T) C.f;
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}
- * FT f; this.f = x;
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}
- * static FT f; C.f = arg;
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}
- * T m(A*); (T) this.m(arg*);
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}
- * static T m(A*); (T) C.m(arg*);
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}
- * T m(A*); (T) super.m(arg*);
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}
- * C(A*); (T) new C(arg*);
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}
- * (static)? FT f; (FT) aField.get(thisOrNull);
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}
- * (static)? FT f; aField.set(thisOrNull, arg);
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}
- * (static)? T m(A*); (T) aMethod.invoke(thisOrNull, arg*);
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}
- * C(A*); (C) aConstructor.newInstance(arg*);
- *
- *
- * {@linkplain java.dyn.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}
- * (static)? T m(A*); (T) aMethod.invoke(thisOrNull, arg*);
- *
- *
- *
- * Here, the type {@code C} is the class or interface being searched for a member,
- * documented as a parameter named {@code refc} in the lookup methods.
- * The method or constructor type {@code MT} is composed from the return type {@code T}
- * and the sequence of argument types {@code A*}.
- * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
- * The formal parameter {@code this} stands for the self-reference of type {@code C};
- * if it is present, it is always the leading argument to the method handle invocation.
- * The name {@code arg} stands for all the other method handle arguments.
- * In the code examples for the Core Reflection API, the name {@code thisOrNull}
- * stands for a null reference if the accessed method or field is static,
- * and {@code this} otherwise.
- * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
- * for reflective objects corresponding to the given members.
- *
- * The equivalence between looked-up method handles and underlying
- * class members can break down in a few ways:
- *
- * If {@code C} is not symbolically accessible from the lookup class's loader,
- * the lookup can still succeed, even when there is no equivalent
- * Java expression or bytecoded constant.
- * Likewise, if {@code T} or {@code MT}
- * is not symbolically accessible from the lookup class's loader,
- * the lookup can still succeed.
- * For example, lookups for {@code MethodHandle.invokeExact} and
- * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
- * If there is a security manager installed, it can forbid the lookup
- * on various grounds (see below ).
- * By contrast, the {@code ldc} instruction is not subject to
- * security manager checks.
- *
- *
- * Access checking
- * Access checks are applied in the factory methods of {@code Lookup},
- * when a method handle is created.
- * This is a key difference from the Core Reflection API, since
- * {@link java.lang.reflect.Method#invoke Method.invoke}
- * performs access checking against every caller, on every call.
- *
- * All access checks start from a {@code Lookup} object, which
- * compares its recorded lookup class against all requests to
- * create method handles.
- * A single {@code Lookup} object can be used to create any number
- * of access-checked method handles, all checked against a single
- * lookup class.
- *
- * A {@code Lookup} object can be shared with other trusted code,
- * such as a metaobject protocol.
- * A shared {@code Lookup} object delegates the capability
- * to create method handles on private members of the lookup class.
- * Even if privileged code uses the {@code Lookup} object,
- * the access checking is confined to the privileges of the
- * original lookup class.
- *
- * A lookup can fail, because
- * the containing class is not accessible to the lookup class, or
- * because the desired class member is missing, or because the
- * desired class member is not accessible to the lookup class.
- * In any of these cases, a {@code ReflectiveOperationException} will be
- * thrown from the attempted lookup. The exact class will be one of
- * the following:
- *
- * NoSuchMethodException — if a method is requested but does not exist
- * NoSuchFieldException — if a field is requested but does not exist
- * IllegalAccessException — if the member exists but an access check fails
- *
- *
- * In general, the conditions under which a method handle may be
- * looked up for a method {@code M} are exactly equivalent to the conditions
- * under which the lookup class could have compiled and resolved a call to {@code M}.
- * And the effect of invoking the method handle resulting from the lookup
- * is exactly equivalent to executing the compiled and resolved call to {@code M}.
- * The same point is true of fields and constructors.
- *
- * In some cases, access between nested classes is obtained by the Java compiler by creating
- * an wrapper method to access a private method of another class
- * in the same top-level declaration.
- * For example, a nested class {@code C.D}
- * can access private members within other related classes such as
- * {@code C}, {@code C.D.E}, or {@code C.B},
- * but the Java compiler may need to generate wrapper methods in
- * those related classes. In such cases, a {@code Lookup} object on
- * {@code C.E} would be unable to those private members.
- * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
- * which can transform a lookup on {@code C.E} into one on any of those other
- * classes, without special elevation of privilege.
- *
- * Although bytecode instructions can only refer to classes in
- * a related class loader, this API can search for methods in any
- * class, as long as a reference to its {@code Class} object is
- * available. Such cross-loader references are also possible with the
- * Core Reflection API, and are impossible to bytecode instructions
- * such as {@code invokestatic} or {@code getfield}.
- * There is a {@linkplain java.lang.SecurityManager security manager API}
- * to allow applications to check such cross-loader references.
- * These checks apply to both the {@code MethodHandles.Lookup} API
- * and the Core Reflection API
- * (as found on {@link java.lang.Class Class}).
- *
- * Access checks only apply to named and reflected methods,
- * constructors, and fields.
- * Other method handle creation methods, such as
- * {@link #convertArguments MethodHandles.convertArguments},
- * do not require any access checks, and are done
- * with static methods of {@link MethodHandles},
- * independently of any {@code Lookup} object.
- *
- *
Security manager interactions
- *
- * If a security manager is present, member lookups are subject to
- * additional checks.
- * From one to four calls are made to the security manager.
- * Any of these calls can refuse access by throwing a
- * {@link java.lang.SecurityException SecurityException}.
- * Define {@code smgr} as the security manager,
- * {@code refc} as the containing class in which the member
- * is being sought, and {@code defc} as the class in which the
- * member is actually defined.
- * The calls are made according to the following rules:
- *
- * In all cases, {@link SecurityManager#checkMemberAccess
- * smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
- * If the class loader of the lookup class is not
- * the same as or an ancestor of the class loader of {@code refc},
- * then {@link SecurityManager#checkPackageAccess
- * smgr.checkPackageAccess(refcPkg)} is called,
- * where {@code refcPkg} is the package of {@code refc}.
- * If the retrieved member is not public,
- * {@link SecurityManager#checkMemberAccess
- * smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
- * (Note that {@code defc} might be the same as {@code refc}.)
- * If the retrieved member is not public,
- * and if {@code defc} and {@code refc} are in different class loaders,
- * and if the class loader of the lookup class is not
- * the same as or an ancestor of the class loader of {@code defc},
- * then {@link SecurityManager#checkPackageAccess
- * smgr.checkPackageAccess(defcPkg)} is called,
- * where {@code defcPkg} is the package of {@code defc}.
- *
- * In all cases, the requesting class presented to the security
- * manager will be the lookup class from the current {@code Lookup} object.
- */
- public static final
- class Lookup {
- /** The class on behalf of whom the lookup is being performed. */
- private final Class> lookupClass;
-
- /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
- private final int allowedModes;
-
- /** A single-bit mask representing {@code public} access,
- * which may contribute to the result of {@link #lookupModes lookupModes}.
- * The value, {@code 0x01}, happens to be the same as the value of the
- * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
- */
- public static final int PUBLIC = Modifier.PUBLIC;
-
- /** A single-bit mask representing {@code private} access,
- * which may contribute to the result of {@link #lookupModes lookupModes}.
- * The value, {@code 0x02}, happens to be the same as the value of the
- * {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
- */
- public static final int PRIVATE = Modifier.PRIVATE;
-
- /** A single-bit mask representing {@code protected} access,
- * which may contribute to the result of {@link #lookupModes lookupModes}.
- * The value, {@code 0x04}, happens to be the same as the value of the
- * {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
- */
- public static final int PROTECTED = Modifier.PROTECTED;
-
- /** A single-bit mask representing {@code package} access (default access),
- * which may contribute to the result of {@link #lookupModes lookupModes}.
- * The value is {@code 0x08}, which does not correspond meaningfully to
- * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
- */
- public static final int PACKAGE = Modifier.STATIC;
-
- private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
- private static final int TRUSTED = -1;
-
- private static int fixmods(int mods) {
- mods &= (ALL_MODES - PACKAGE);
- return (mods != 0) ? mods : PACKAGE;
- }
-
- /** Tells which class is performing the lookup. It is this class against
- * which checks are performed for visibility and access permissions.
- *
- * The class implies a maximum level of access permission,
- * but the permissions may be additionally limited by the bitmask
- * {@link #lookupModes lookupModes}, which controls whether non-public members
- * can be accessed.
- */
- public Class> lookupClass() {
- return lookupClass;
- }
-
- // This is just for calling out to MethodHandleImpl.
- private Class> lookupClassOrNull() {
- return (allowedModes == TRUSTED) ? null : lookupClass;
- }
-
- /** Tells which access-protection classes of members this lookup object can produce.
- * The result is a bit-mask of the bits
- * {@linkplain #PUBLIC PUBLIC (0x01)},
- * {@linkplain #PRIVATE PRIVATE (0x02)},
- * {@linkplain #PROTECTED PROTECTED (0x04)},
- * and {@linkplain #PACKAGE PACKAGE (0x08)}.
- *
- * A freshly-created lookup object
- * on the {@linkplain java.dyn.MethodHandles#lookup() caller's class}
- * has all possible bits set, since the caller class can access all its own members.
- * A lookup object on a new lookup class
- * {@linkplain java.dyn.MethodHandles.Lookup#in created from a previous lookup object}
- * may have some mode bits set to zero.
- * The purpose of this is to restrict access via the new lookup object,
- * so that it can access only names which can be reached by the original
- * lookup object, and also by the new lookup class.
- */
- public int lookupModes() {
- return allowedModes & ALL_MODES;
- }
-
- /** Embody the current class (the lookupClass) as a lookup class
- * for method handle creation.
- * Must be called by from a method in this package,
- * which in turn is called by a method not in this package.
- *
- * Also, don't make it private, lest javac interpose
- * an access$N method.
- */
- Lookup() {
- this(getCallerClassAtEntryPoint(), ALL_MODES);
- // make sure we haven't accidentally picked up a privileged class:
- checkUnprivilegedlookupClass(lookupClass);
- }
-
- Lookup(Access token, Class> lookupClass) {
- this(lookupClass, ALL_MODES);
- Access.check(token);
- }
-
- private Lookup(Class> lookupClass, int allowedModes) {
- this.lookupClass = lookupClass;
- this.allowedModes = allowedModes;
- }
-
- /**
- * Creates a lookup on the specified new lookup class.
- * The resulting object will report the specified
- * class as its own {@link #lookupClass lookupClass}.
- *
- * However, the resulting {@code Lookup} object is guaranteed
- * to have no more access capabilities than the original.
- * In particular, access capabilities can be lost as follows:
- * If the new lookup class differs from the old one,
- * protected members will not be accessible by virtue of inheritance.
- * (Protected members may continue to be accessible because of package sharing.)
- * If the new lookup class is in a different package
- * than the old one, protected and default (package) members will not be accessible.
- * If the new lookup class is not within the same package member
- * as the old one, private members will not be accessible.
- * If the new lookup class is not accessible to the old lookup class,
- * then no members, not even public members, will be accessible.
- * (In all other cases, public members will continue to be accessible.)
- *
- *
- * @param requestedLookupClass the desired lookup class for the new lookup object
- * @return a lookup object which reports the desired lookup class
- * @throws NullPointerException if the argument is null
- */
- public Lookup in(Class> requestedLookupClass) {
- requestedLookupClass.getClass(); // null check
- if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
- return new Lookup(requestedLookupClass, ALL_MODES);
- if (requestedLookupClass == this.lookupClass)
- return this; // keep same capabilities
- int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
- if ((newModes & PACKAGE) != 0
- && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
- newModes &= ~(PACKAGE|PRIVATE);
- }
- // Allow nestmate lookups to be created without special privilege:
- if ((newModes & PRIVATE) != 0
- && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
- newModes &= ~PRIVATE;
- }
- if (newModes == PUBLIC
- && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass)) {
- // The requested class it not accessible from the lookup class.
- // No permissions.
- newModes = 0;
- }
- checkUnprivilegedlookupClass(requestedLookupClass);
- return new Lookup(requestedLookupClass, newModes);
- }
-
- // Make sure outer class is initialized first.
- static { IMPL_TOKEN.getClass(); }
-
- /** Version of lookup which is trusted minimally.
- * It can only be used to create method handles to
- * publicly accessible members.
- */
- static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
-
- /** Package-private version of lookup which is trusted. */
- static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
- static { MethodHandleImpl.initLookup(IMPL_TOKEN, IMPL_LOOKUP); }
-
- private static void checkUnprivilegedlookupClass(Class> lookupClass) {
- String name = lookupClass.getName();
- if (name.startsWith("java.dyn.") || name.startsWith("sun.dyn."))
- throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
- }
-
- /**
- * Displays the name of the class from which lookups are to be made.
- * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
- * If there are restrictions on the access permitted to this lookup,
- * this is indicated by adding a suffix to the class name, consisting
- * of a slash and a keyword. The keyword represents the strongest
- * allowed access, and is chosen as follows:
- *
- * If no access is allowed, the suffix is "/noaccess".
- * If only public access is allowed, the suffix is "/public".
- * If only public and package access are allowed, the suffix is "/package".
- * If only public, package, and private access are allowed, the suffix is "/private".
- *
- * If none of the above cases apply, it is the case that full
- * access (public, package, private, and protected) is allowed.
- * In this case, no suffix is added.
- * This is true only of an object obtained originally from
- * {@link java.dyn.MethodHandles#lookup MethodHandles.lookup}.
- * Objects created by {@link java.dyn.MethodHandles.Lookup#in Lookup.in}
- * always have restricted access, and will display a suffix.
- *
- * (It may seem strange that protected access should be
- * stronger than private access. Viewed independently from
- * package access, protected access is the first to be lost,
- * because it requires a direct subclass relationship between
- * caller and callee.)
- * @see #in
- */
- @Override
- public String toString() {
- String cname = lookupClass.getName();
- switch (allowedModes) {
- case 0: // no privileges
- return cname + "/noaccess";
- case PUBLIC:
- return cname + "/public";
- case PUBLIC|PACKAGE:
- return cname + "/package";
- case ALL_MODES & ~PROTECTED:
- return cname + "/private";
- case ALL_MODES:
- return cname;
- case TRUSTED:
- return "/trusted"; // internal only; not exported
- default: // Should not happen, but it's a bitfield...
- cname = cname + "/" + Integer.toHexString(allowedModes);
- assert(false) : cname;
- return cname;
- }
- }
-
- // call this from an entry point method in Lookup with extraFrames=0.
- private static Class> getCallerClassAtEntryPoint() {
- final int CALLER_DEPTH = 4;
- // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
- // 2: Lookup., 3: MethodHandles.*, 4: caller
- // Note: This should be the only use of getCallerClass in this file.
- assert(Reflection.getCallerClass(CALLER_DEPTH-1) == MethodHandles.class);
- return Reflection.getCallerClass(CALLER_DEPTH);
- }
-
- /**
- * Produces a method handle for a static method.
- * The type of the method handle will be that of the method.
- * (Since static methods do not take receivers, there is no
- * additional receiver argument inserted into the method handle type,
- * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
- * The method and all its argument types must be accessible to the lookup class.
- * If the method's class has not yet been initialized, that is done
- * immediately, before the method handle is returned.
- *
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * @param refc the class from which the method is accessed
- * @param name the name of the method
- * @param type the type of the method
- * @return the desired method handle
- * @throws NoSuchMethodException if the method does not exist
- * @throws IllegalAccessException if access checking fails, or if the method is not {@code static}
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public
- MethodHandle findStatic(Class> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- MemberName method = resolveOrFail(refc, name, type, true);
- checkMethod(refc, method, true);
- return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull());
- }
-
- /**
- * Produces a method handle for a virtual method.
- * The type of the method handle will be that of the method,
- * with the receiver type (usually {@code refc}) prepended.
- * The method and all its argument types must be accessible to the lookup class.
- *
- * When called, the handle will treat the first argument as a receiver
- * and dispatch on the receiver's type to determine which method
- * implementation to enter.
- * (The dispatching action is identical with that performed by an
- * {@code invokevirtual} or {@code invokeinterface} instruction.)
- *
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- *
- * Because of the general equivalence between {@code invokevirtual}
- * instructions and method handles produced by {@code findVirtual},
- * if the class is {@code MethodHandle} and the name string is
- * {@code invokeExact} or {@code invokeGeneric}, the resulting
- * method handle is equivalent to one produced by
- * {@link java.dyn.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
- * {@link java.dyn.MethodHandles#genericInvoker MethodHandles.genericInvoker}
- * with the same {@code type} argument.
- *
- * @param refc the class or interface from which the method is accessed
- * @param name the name of the method
- * @param type the type of the method, with the receiver argument omitted
- * @return the desired method handle
- * @throws NoSuchMethodException if the method does not exist
- * @throws IllegalAccessException if access checking fails, or if the method is {@code static}
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findVirtual(Class> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- MemberName method = resolveOrFail(refc, name, type, false);
- checkMethod(refc, method, false);
- MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
- return restrictProtectedReceiver(method, mh);
- }
-
- /**
- * Produces a method handle which creates an object and initializes it, using
- * the constructor of the specified type.
- * The parameter types of the method handle will be those of the constructor,
- * while the return type will be a reference to the constructor's class.
- * The constructor and all its argument types must be accessible to the lookup class.
- * If the constructor's class has not yet been initialized, that is done
- * immediately, before the method handle is returned.
- *
- * Note: The requested type must have a return type of {@code void}.
- * This is consistent with the JVM's treatment of constructor type descriptors.
- *
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
- * @param refc the class or interface from which the method is accessed
- * @param type the type of the method, with the receiver argument omitted, and a void return type
- * @return the desired method handle
- * @throws NoSuchMethodException if the constructor does not exist
- * @throws IllegalAccessException if access checking fails
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findConstructor(Class> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- String name = "";
- MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
- assert(ctor.isConstructor());
- checkAccess(refc, ctor);
- MethodHandle rawMH = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull());
- MethodHandle allocMH = MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawMH);
- return fixVarargs(allocMH, rawMH);
- }
-
- /** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
- private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
- boolean va1 = mh.isVarargsCollector();
- boolean va2 = matchMH.isVarargsCollector();
- if (va1 == va2) {
- return mh;
- } else if (va2) {
- MethodType type = mh.type();
- int arity = type.parameterCount();
- return mh.asVarargsCollector(type.parameterType(arity-1));
- } else {
- throw new InternalError("already varargs, but template is not: "+mh);
- }
- }
-
- /**
- * Produces an early-bound method handle for a virtual method,
- * as if called from an {@code invokespecial}
- * instruction from {@code caller}.
- * The type of the method handle will be that of the method,
- * with a suitably restricted receiver type (such as {@code caller}) prepended.
- * The method and all its argument types must be accessible
- * to the caller.
- *
- * When called, the handle will treat the first argument as a receiver,
- * but will not dispatch on the receiver's type.
- * (This direct invocation action is identical with that performed by an
- * {@code invokespecial} instruction.)
- *
- * If the explicitly specified caller class is not identical with the
- * lookup class, or if this lookup object does not have private access
- * privileges, the access fails.
- *
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * @param refc the class or interface from which the method is accessed
- * @param name the name of the method (which must not be "<init>")
- * @param type the type of the method, with the receiver argument omitted
- * @param specialCaller the proposed calling class to perform the {@code invokespecial}
- * @return the desired method handle
- * @throws NoSuchMethodException if the method does not exist
- * @throws IllegalAccessException if access checking fails
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findSpecial(Class> refc, String name, MethodType type,
- Class> specialCaller) throws NoSuchMethodException, IllegalAccessException {
- checkSpecialCaller(specialCaller);
- MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
- checkMethod(refc, method, false);
- MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, specialCaller);
- return restrictReceiver(method, mh, specialCaller);
- }
-
- /**
- * Produces a method handle giving read access to a non-static field.
- * The type of the method handle will have a return type of the field's
- * value type.
- * The method handle's single argument will be the instance containing
- * the field.
- * Access checking is performed immediately on behalf of the lookup class.
- * @param refc the class or interface from which the method is accessed
- * @param name the field's name
- * @param type the field's type
- * @return a method handle which can load values from the field
- * @throws NoSuchFieldException if the field does not exist
- * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findGetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
- return makeAccessor(refc, name, type, false, false);
- }
-
- /**
- * Produces a method handle giving write access to a non-static field.
- * The type of the method handle will have a void return type.
- * The method handle will take two arguments, the instance containing
- * the field, and the value to be stored.
- * The second argument will be of the field's value type.
- * Access checking is performed immediately on behalf of the lookup class.
- * @param refc the class or interface from which the method is accessed
- * @param name the field's name
- * @param type the field's type
- * @return a method handle which can store values into the field
- * @throws NoSuchFieldException if the field does not exist
- * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findSetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
- return makeAccessor(refc, name, type, false, true);
- }
-
- /**
- * Produces a method handle giving read access to a static field.
- * The type of the method handle will have a return type of the field's
- * value type.
- * The method handle will take no arguments.
- * Access checking is performed immediately on behalf of the lookup class.
- * @param refc the class or interface from which the method is accessed
- * @param name the field's name
- * @param type the field's type
- * @return a method handle which can load values from the field
- * @throws NoSuchFieldException if the field does not exist
- * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findStaticGetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
- return makeAccessor(refc, name, type, true, false);
- }
-
- /**
- * Produces a method handle giving write access to a static field.
- * The type of the method handle will have a void return type.
- * The method handle will take a single
- * argument, of the field's value type, the value to be stored.
- * Access checking is performed immediately on behalf of the lookup class.
- * @param refc the class or interface from which the method is accessed
- * @param name the field's name
- * @param type the field's type
- * @return a method handle which can store values into the field
- * @throws NoSuchFieldException if the field does not exist
- * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle findStaticSetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
- return makeAccessor(refc, name, type, true, true);
- }
-
- /**
- * Produces an early-bound method handle for a non-static method.
- * The receiver must have a supertype {@code defc} in which a method
- * of the given name and type is accessible to the lookup class.
- * The method and all its argument types must be accessible to the lookup class.
- * The type of the method handle will be that of the method,
- * without any insertion of an additional receiver parameter.
- * The given receiver will be bound into the method handle,
- * so that every call to the method handle will invoke the
- * requested method on the given receiver.
- *
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set
- * and the trailing array argument is not the only argument.
- * (If the trailing array argument is the only argument,
- * the given receiver value will be bound to it.)
- *
- * This is equivalent to the following code:
- *
-MethodHandle mh0 = {@link #findVirtual findVirtual}(defc, name, type);
-MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
-MethodType mt1 = mh1.type();
-if (mh0.isVarargsCollector() && mt1.parameterCount() > 0) {
- mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
-return mh1;
- *
- * where {@code defc} is either {@code receiver.getClass()} or a super
- * type of that class, in which the requested method is accessible
- * to the lookup class.
- * (Note that {@code bindTo} does not preserve variable arity.)
- * @param receiver the object from which the method is accessed
- * @param name the name of the method
- * @param type the type of the method, with the receiver argument omitted
- * @return the desired method handle
- * @throws NoSuchMethodException if the method does not exist
- * @throws IllegalAccessException if access checking fails
- * @exception SecurityException if a security manager is present and it
- * refuses access
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
- Class extends Object> refc = receiver.getClass(); // may get NPE
- MemberName method = resolveOrFail(refc, name, type, false);
- checkMethod(refc, method, false);
- MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
- MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, dmh, receiver);
- if (bmh == null)
- throw newNoAccessException(method, this);
- if (dmh.type().parameterCount() == 0)
- return dmh; // bound the trailing parameter; no varargs possible
- return fixVarargs(bmh, dmh);
- }
-
- /**
- * Make a direct method handle to m , if the lookup class has permission.
- * If m is non-static, the receiver argument is treated as an initial argument.
- * If m is virtual, overriding is respected on every call.
- * Unlike the Core Reflection API, exceptions are not wrapped.
- * The type of the method handle will be that of the method,
- * with the receiver type prepended (but only if it is non-static).
- * If the method's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class.
- * If m is not public, do not share the resulting handle with untrusted parties.
- *
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * @param m the reflected method
- * @return a method handle which can invoke the reflected method
- * @throws IllegalAccessException if access checking fails
- * @throws NullPointerException if the argument is null
- */
- public MethodHandle unreflect(Method m) throws IllegalAccessException {
- MemberName method = new MemberName(m);
- assert(method.isMethod());
- if (!m.isAccessible()) checkMethod(method.getDeclaringClass(), method, method.isStatic());
- MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClassOrNull());
- if (!m.isAccessible()) mh = restrictProtectedReceiver(method, mh);
- return mh;
- }
-
- /**
- * Produces a method handle for a reflected method.
- * It will bypass checks for overriding methods on the receiver,
- * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
- * The type of the method handle will be that of the method,
- * with the special caller type prepended (and not the receiver of the method).
- * If the method's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class,
- * as if {@code invokespecial} instruction were being linked.
- *
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the method's variable arity modifier bit ({@code 0x0080}) is set.
- * @param m the reflected method
- * @param specialCaller the class nominally calling the method
- * @return a method handle which can invoke the reflected method
- * @throws IllegalAccessException if access checking fails
- * @throws NullPointerException if any argument is null
- */
- public MethodHandle unreflectSpecial(Method m, Class> specialCaller) throws IllegalAccessException {
- checkSpecialCaller(specialCaller);
- MemberName method = new MemberName(m);
- assert(method.isMethod());
- // ignore m.isAccessible: this is a new kind of access
- checkMethod(m.getDeclaringClass(), method, false);
- MethodHandle mh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClassOrNull());
- return restrictReceiver(method, mh, specialCaller);
- }
-
- /**
- * Produces a method handle for a reflected constructor.
- * The type of the method handle will be that of the constructor,
- * with the return type changed to the declaring class.
- * The method handle will perform a {@code newInstance} operation,
- * creating a new instance of the constructor's class on the
- * arguments passed to the method handle.
- *
- * If the constructor's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class.
- *
- * The returned method handle will have
- * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
- * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
- * @param c the reflected constructor
- * @return a method handle which can invoke the reflected constructor
- * @throws IllegalAccessException if access checking fails
- * @throws NullPointerException if the argument is null
- */
- public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
- MemberName ctor = new MemberName(c);
- assert(ctor.isConstructor());
- if (!c.isAccessible()) checkAccess(c.getDeclaringClass(), ctor);
- MethodHandle rawCtor = MethodHandleImpl.findMethod(IMPL_TOKEN, ctor, false, lookupClassOrNull());
- MethodHandle allocator = MethodHandleImpl.makeAllocator(IMPL_TOKEN, rawCtor);
- return fixVarargs(allocator, rawCtor);
- }
-
- /**
- * Produces a method handle giving read access to a reflected field.
- * The type of the method handle will have a return type of the field's
- * value type.
- * If the field is static, the method handle will take no arguments.
- * Otherwise, its single argument will be the instance containing
- * the field.
- * If the method's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class.
- * @param f the reflected field
- * @return a method handle which can load values from the reflected field
- * @throws IllegalAccessException if access checking fails
- * @throws NullPointerException if the argument is null
- */
- public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
- return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false);
- }
-
- /**
- * Produces a method handle giving write access to a reflected field.
- * The type of the method handle will have a void return type.
- * If the field is static, the method handle will take a single
- * argument, of the field's value type, the value to be stored.
- * Otherwise, the two arguments will be the instance containing
- * the field, and the value to be stored.
- * If the method's {@code accessible} flag is not set,
- * access checking is performed immediately on behalf of the lookup class.
- * @param f the reflected field
- * @return a method handle which can store values into the reflected field
- * @throws IllegalAccessException if access checking fails
- * @throws NullPointerException if the argument is null
- */
- public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
- return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true);
- }
-
- /// Helper methods, all package-private.
-
- MemberName resolveOrFail(Class> refc, String name, Class> type, boolean isStatic) throws NoSuchFieldException, IllegalAccessException {
- checkSymbolicClass(refc); // do this before attempting to resolve
- name.getClass(); type.getClass(); // NPE
- int mods = (isStatic ? Modifier.STATIC : 0);
- return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
- NoSuchFieldException.class);
- }
-
- MemberName resolveOrFail(Class> refc, String name, MethodType type, boolean isStatic) throws NoSuchMethodException, IllegalAccessException {
- checkSymbolicClass(refc); // do this before attempting to resolve
- name.getClass(); type.getClass(); // NPE
- int mods = (isStatic ? Modifier.STATIC : 0);
- return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
- NoSuchMethodException.class);
- }
-
- MemberName resolveOrFail(Class> refc, String name, MethodType type, boolean isStatic,
- boolean searchSupers, Class> specialCaller) throws NoSuchMethodException, IllegalAccessException {
- checkSymbolicClass(refc); // do this before attempting to resolve
- name.getClass(); type.getClass(); // NPE
- int mods = (isStatic ? Modifier.STATIC : 0);
- return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller,
- NoSuchMethodException.class);
- }
-
- void checkSymbolicClass(Class> refc) throws IllegalAccessException {
- Class> caller = lookupClassOrNull();
- if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
- throw newNoAccessException("symbolic reference class is not public", new MemberName(refc), this);
- }
-
- void checkMethod(Class> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
- String message;
- if (m.isConstructor())
- message = "expected a method, not a constructor";
- else if (!m.isMethod())
- message = "expected a method";
- else if (wantStatic != m.isStatic())
- message = wantStatic ? "expected a static method" : "expected a non-static method";
- else
- { checkAccess(refc, m); return; }
- throw newNoAccessException(message, m, this);
- }
-
- void checkAccess(Class> refc, MemberName m) throws IllegalAccessException {
- int allowedModes = this.allowedModes;
- if (allowedModes == TRUSTED) return;
- int mods = m.getModifiers();
- if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
- return; // common case
- int requestedModes = fixmods(mods); // adjust 0 => PACKAGE
- if ((requestedModes & allowedModes) != 0
- && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
- mods, lookupClass()))
- return;
- if (((requestedModes & ~allowedModes) & PROTECTED) != 0
- && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
- // Protected members can also be checked as if they were package-private.
- return;
- throw newNoAccessException(accessFailedMessage(refc, m), m, this);
- }
-
- String accessFailedMessage(Class> refc, MemberName m) {
- Class> defc = m.getDeclaringClass();
- int mods = m.getModifiers();
- // check the class first:
- boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
- (defc == refc ||
- Modifier.isPublic(refc.getModifiers())));
- if (!classOK && (allowedModes & PACKAGE) != 0) {
- classOK = (VerifyAccess.isClassAccessible(defc, lookupClass()) &&
- (defc == refc ||
- VerifyAccess.isClassAccessible(refc, lookupClass())));
- }
- if (!classOK)
- return "class is not public";
- if (Modifier.isPublic(mods))
- return "access to public member failed"; // (how?)
- if (Modifier.isPrivate(mods))
- return "member is private";
- if (Modifier.isProtected(mods))
- return "member is protected";
- return "member is private to package";
- }
-
- private static final boolean ALLOW_NESTMATE_ACCESS = false;
-
- void checkSpecialCaller(Class> specialCaller) throws IllegalAccessException {
- if (allowedModes == TRUSTED) return;
- if ((allowedModes & PRIVATE) == 0
- || (specialCaller != lookupClass()
- && !(ALLOW_NESTMATE_ACCESS &&
- VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
- throw newNoAccessException("no private access for invokespecial",
- new MemberName(specialCaller), this);
- }
-
- MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
- // The accessing class only has the right to use a protected member
- // on itself or a subclass. Enforce that restriction, from JVMS 5.4.4, etc.
- if (!method.isProtected() || method.isStatic()
- || allowedModes == TRUSTED
- || method.getDeclaringClass() == lookupClass()
- || (ALLOW_NESTMATE_ACCESS &&
- VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
- return mh;
- else
- return restrictReceiver(method, mh, lookupClass());
- }
- MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class> caller) throws IllegalAccessException {
- assert(!method.isStatic());
- Class> defc = method.getDeclaringClass(); // receiver type of mh is too wide
- if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
- throw newNoAccessException("caller class must be a subclass below the method", method, caller);
- }
- MethodType rawType = mh.type();
- if (rawType.parameterType(0) == caller) return mh;
- MethodType narrowType = rawType.changeParameterType(0, caller);
- MethodHandle narrowMH = MethodHandleImpl.convertArguments(IMPL_TOKEN, mh, narrowType, rawType, null);
- return fixVarargs(narrowMH, mh);
- }
-
- MethodHandle makeAccessor(Class> refc, String name, Class> type,
- boolean isStatic, boolean isSetter) throws NoSuchFieldException, IllegalAccessException {
- MemberName field = resolveOrFail(refc, name, type, isStatic);
- if (isStatic != field.isStatic())
- throw newNoAccessException(isStatic
- ? "expected a static field"
- : "expected a non-static field",
- field, this);
- return makeAccessor(refc, field, false, isSetter);
- }
-
- MethodHandle makeAccessor(Class> refc, MemberName field,
- boolean trusted, boolean isSetter) throws IllegalAccessException {
- assert(field.isField());
- if (trusted)
- return MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull());
- checkAccess(refc, field);
- MethodHandle mh = MethodHandleImpl.accessField(IMPL_TOKEN, field, isSetter, lookupClassOrNull());
- return restrictProtectedReceiver(field, mh);
- }
- }
-
- /**
- * Produces a method handle giving read access to elements of an array.
- * The type of the method handle will have a return type of the array's
- * element type. Its first argument will be the array type,
- * and the second will be {@code int}.
- * @param arrayClass an array type
- * @return a method handle which can load values from the given array type
- * @throws NullPointerException if the argument is null
- * @throws IllegalArgumentException if arrayClass is not an array type
- */
- public static
- MethodHandle arrayElementGetter(Class> arrayClass) throws IllegalArgumentException {
- return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, false);
- }
-
- /**
- * Produces a method handle giving write access to elements of an array.
- * The type of the method handle will have a void return type.
- * Its last argument will be the array's element type.
- * The first and second arguments will be the array type and int.
- * @return a method handle which can store values into the array type
- * @throws NullPointerException if the argument is null
- * @throws IllegalArgumentException if arrayClass is not an array type
- */
- public static
- MethodHandle arrayElementSetter(Class> arrayClass) throws IllegalArgumentException {
- return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, true);
- }
-
- /// method handle invocation (reflective style)
-
- /**
- * Produces a method handle which will invoke any method handle of the
- * given {@code type} on a standard set of {@code Object} type arguments
- * and a single trailing {@code Object[]} array.
- * The resulting invoker will be a method handle with the following
- * arguments:
- *
- * a single {@code MethodHandle} target
- * zero or more {@code Object} values (counted by {@code objectArgCount})
- * an {@code Object[]} array containing more arguments
- *
- *
- * The invoker will behave like a call to {@link MethodHandle#invokeGeneric invokeGeneric} with
- * the indicated {@code type}.
- * That is, if the target is exactly of the given {@code type}, it will behave
- * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
- * is used to convert the target to the required {@code type}.
- *
- * The type of the returned invoker will not be the given {@code type}, but rather
- * will have all parameter and return types replaced by {@code Object}, except for
- * the last parameter type, which will be the array type {@code Object[]}.
- *
- * Before invoking its target, the invoker will spread the varargs array, apply
- * reference casts as necessary, and unbox and widen primitive arguments.
- * The return value of the invoker will be an {@code Object} reference,
- * boxing a primitive value if the original type returns a primitive,
- * and always null if the original type returns void.
- *
- * This method is equivalent to the following code (though it may be more efficient):
- *
-MethodHandle invoker = MethodHandles.genericInvoker(type);
-int spreadArgCount = type.parameterCount - objectArgCount;
-invoker = invoker.asSpreader(Object[].class, spreadArgCount);
-return invoker;
- *
- *
- * This method throws no reflective or security exceptions.
- * @param type the desired target type
- * @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
- * @return a method handle suitable for invoking any method handle of the given type
- */
- static public
- MethodHandle spreadInvoker(MethodType type, int objectArgCount) {
- if (objectArgCount < 0 || objectArgCount > type.parameterCount())
- throw new IllegalArgumentException("bad argument count "+objectArgCount);
- return invokers(type).spreadInvoker(objectArgCount);
- }
-
- /**
- * Produces a special invoker method handle which can be used to
- * invoke any method handle of the given type, as if by {@code invokeExact}.
- * The resulting invoker will have a type which is
- * exactly equal to the desired type, except that it will accept
- * an additional leading argument of type {@code MethodHandle}.
- *
- * This method is equivalent to the following code (though it may be more efficient):
- *
-publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
- *
- *
- *
- * Discussion:
- * Invoker method handles can be useful when working with variable method handles
- * of unknown types.
- * For example, to emulate an {@code invokeExact} call to a variable method
- * handle {@code M}, extract its type {@code T},
- * look up the invoker method {@code X} for {@code T},
- * and call the invoker method, as {@code X.invokeGeneric(T, A...)}.
- * (It would not work to call {@code X.invokeExact}, since the type {@code T}
- * is unknown.)
- * If spreading, collecting, or other argument transformations are required,
- * they can be applied once to the invoker {@code X} and reused on many {@code M}
- * method handle values, as long as they are compatible with the type of {@code X}.
- *
- * (Note: The invoker method is not available via the Core Reflection API.
- * An attempt to call {@linkplain java.lang.reflect.Method#invoke Method.invoke}
- * on the declared {@code invokeExact} or {@code invokeGeneric} method will raise an
- * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)
- *
- * This method throws no reflective or security exceptions.
- * @param type the desired target type
- * @return a method handle suitable for invoking any method handle of the given type
- */
- static public
- MethodHandle exactInvoker(MethodType type) {
- return invokers(type).exactInvoker();
- }
-
- /**
- * Produces a special invoker method handle which can be used to
- * invoke any method handle of the given type, as if by {@code invokeGeneric}.
- * The resulting invoker will have a type which is
- * exactly equal to the desired type, except that it will accept
- * an additional leading argument of type {@code MethodHandle}.
- *
- * Before invoking its target, the invoker will apply reference casts as
- * necessary and unbox and widen primitive arguments, as if by {@link #convertArguments convertArguments}.
- * The return value of the invoker will be an {@code Object} reference,
- * boxing a primitive value if the original type returns a primitive,
- * and always null if the original type returns void.
- *
- * This method is equivalent to the following code (though it may be more efficient):
- *
-publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
- *
- *
- * This method throws no reflective or security exceptions.
- * @param type the desired target type
- * @return a method handle suitable for invoking any method handle convertible to the given type
- */
- static public
- MethodHandle genericInvoker(MethodType type) {
- return invokers(type).genericInvoker();
- }
-
- static Invokers invokers(MethodType type) {
- return MethodTypeImpl.invokers(IMPL_TOKEN, type);
- }
-
- /**
- * Perform value checking, exactly as if for an adapted method handle.
- * It is assumed that the given value is either null, of type T0,
- * or (if T0 is primitive) of the wrapper type corresponding to T0.
- * The following checks and conversions are made:
- *
- * If T0 and T1 are references, then a cast to T1 is applied.
- * (The types do not need to be related in any particular way.)
- * If T0 and T1 are primitives, then a widening or narrowing
- * conversion is applied, if one exists.
- * If T0 is a primitive and T1 a reference, and
- * T0 has a wrapper type TW, a boxing conversion to TW is applied,
- * possibly followed by a reference conversion.
- * T1 must be TW or a supertype.
- * If T0 is a reference and T1 a primitive, and
- * T1 has a wrapper type TW, an unboxing conversion is applied,
- * possibly preceded by a reference conversion.
- * T0 must be TW or a supertype.
- * If T1 is void, the return value is discarded
- * If T0 is void and T1 a reference, a null value is introduced.
- * If T0 is void and T1 a primitive, a zero value is introduced.
- *
- * If the value is discarded, null will be returned.
- * @param valueType
- * @param value
- * @return the value, converted if necessary
- * @throws java.lang.ClassCastException if a cast fails
- */
- static
- T1 checkValue(Class t0, Class t1, Object value)
- throws ClassCastException
- {
- if (t0 == t1) {
- // no conversion needed; just reassert the same type
- if (t0.isPrimitive())
- return Wrapper.asPrimitiveType(t1).cast(value);
- else
- return Wrapper.OBJECT.convert(value, t1);
- }
- boolean prim0 = t0.isPrimitive(), prim1 = t1.isPrimitive();
- if (!prim0) {
- // check contract with caller
- Wrapper.OBJECT.convert(value, t0);
- if (!prim1) {
- return Wrapper.OBJECT.convert(value, t1);
- }
- // convert reference to primitive by unboxing
- Wrapper w1 = Wrapper.forPrimitiveType(t1);
- return w1.convert(value, t1);
- }
- // check contract with caller:
- Wrapper.asWrapperType(t0).cast(value);
- Wrapper w1 = Wrapper.forPrimitiveType(t1);
- return w1.convert(value, t1);
- }
-
- static
- Object checkValue(Class> T1, Object value)
- throws ClassCastException
- {
- Class> T0;
- if (value == null)
- T0 = Object.class;
- else
- T0 = value.getClass();
- return checkValue(T0, T1, value);
- }
-
- /// method handle modification (creation from other method handles)
-
- /**
- * Produces a method handle which adapts the type of the
- * given method handle to a new type by pairwise argument conversion.
- * The original type and new type must have the same number of arguments.
- * The resulting method handle is guaranteed to report a type
- * which is equal to the desired new type.
- *
- * If the original type and new type are equal, returns target.
- *
- * The following conversions are applied as needed both to
- * arguments and return types. Let T0 and T1 be the differing
- * new and old parameter types (or old and new return types)
- * for corresponding values passed by the new and old method types.
- * Given those types T0, T1, one of the following conversions is applied
- * if possible:
- *
- * If T0 and T1 are references, then a cast to T1 is applied.
- * (The types do not need to be related in any particular way.)
- * If T0 and T1 are primitives, then a Java method invocation
- * conversion (JLS 5.3) is applied, if one exists.
- * If T0 is a primitive and T1 a reference, a boxing
- * conversion is applied if one exists, possibly followed by
- * a reference conversion to a superclass.
- * T1 must be a wrapper class or a supertype of one.
- * If T0 is a reference and T1 a primitive, an unboxing
- * conversion will be applied at runtime, possibly followed
- * by a Java method invocation conversion (JLS 5.3)
- * on the primitive value. (These are the widening conversions.)
- * T0 must be a wrapper class or a supertype of one.
- * (In the case where T0 is Object, these are the conversions
- * allowed by java.lang.reflect.Method.invoke.)
- * If the return type T1 is void, any returned value is discarded
- * If the return type T0 is void and T1 a reference, a null value is introduced.
- * If the return type T0 is void and T1 a primitive, a zero value is introduced.
- *
- * @param target the method handle to invoke after arguments are retyped
- * @param newType the expected type of the new method handle
- * @return a method handle which delegates to {@code target} after performing
- * any necessary argument conversions, and arranges for any
- * necessary return value conversions
- * @throws NullPointerException if either argument is null
- * @throws WrongMethodTypeException if the conversion cannot be made
- * @see MethodHandle#asType
- * @see MethodHandles#explicitCastArguments
- */
- public static
- MethodHandle convertArguments(MethodHandle target, MethodType newType) {
- MethodType oldType = target.type();
- if (oldType.equals(newType))
- return target;
- MethodHandle res = null;
- try {
- res = MethodHandleImpl.convertArguments(IMPL_TOKEN, target,
- newType, oldType, null);
- } catch (IllegalArgumentException ex) {
- }
- if (res == null)
- throw new WrongMethodTypeException("cannot convert to "+newType+": "+target);
- return res;
- }
-
- /**
- * Produces a method handle which adapts the type of the
- * given method handle to a new type by pairwise argument conversion.
- * The original type and new type must have the same number of arguments.
- * The resulting method handle is guaranteed to report a type
- * which is equal to the desired new type.
- *
- * If the original type and new type are equal, returns target.
- *
- * The same conversions are allowed as for {@link #convertArguments convertArguments},
- * and some additional conversions are also applied if those conversions fail.
- * Given types T0, T1, one of the following conversions is applied
- * in addition, if the conversions specified for {@code convertArguments}
- * would be insufficient:
- *
- * If T0 and T1 are references, and T1 is an interface type,
- * then the value of type T0 is passed as a T1 without a cast.
- * (This treatment of interfaces follows the usage of the bytecode verifier.)
- * If T0 and T1 are primitives and one is boolean,
- * the boolean is treated as a one-bit unsigned integer.
- * (This treatment follows the usage of the bytecode verifier.)
- * A conversion from another primitive type behaves as if
- * it first converts to byte, and then masks all but the low bit.
- * If a primitive value would be converted by {@code convertArguments}
- * using Java method invocation conversion (JLS 5.3),
- * Java casting conversion (JLS 5.5) may be used also.
- * This allows primitives to be narrowed as well as widened.
- *
- * @param target the method handle to invoke after arguments are retyped
- * @param newType the expected type of the new method handle
- * @return a method handle which delegates to {@code target} after performing
- * any necessary argument conversions, and arranges for any
- * necessary return value conversions
- * @throws NullPointerException if either argument is null
- * @throws WrongMethodTypeException if the conversion cannot be made
- * @see MethodHandle#asType
- * @see MethodHandles#convertArguments
- */
- public static
- MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
- return convertArguments(target, newType); // FIXME!
- }
-
- /*
- FIXME: Reconcile javadoc with 10/22/2010 EG notes on conversion:
-
- Both converters arrange for their method handles to convert arguments
- and return values. The conversion rules are the same for arguments
- and return values, and depend only on source and target types, S and
- T. The conversions allowed by castConvertArguments are a strict
- superset of those performed by convertArguments.
-
- In all cases, if S and T are references, a simple checkcast is done.
- If neither S nor T is a primitive, no attempt is made to unbox and
- box. A failed conversion throws ClassCastException.
-
- If T is void, the value is dropped.
-
- For compatibility with reflection, if S is void and T is a reference,
- a null value is produced.
-
- For compatibility with reflection, if S is a reference and T is a
- primitive, S is first unboxed and then undergoes primitive conversion.
- In the case of 'convertArguments', only assignment conversion is
- performed (no narrowing primitive conversion).
-
- If S is a primitive, S is boxed, and then the above rules are applied.
- If S and T are both primitives, the boxing will be undetectable; only
- the primitive conversions will be apparent to the user. The key point
- is that if S is a primitive type, the implementation may box it and
- treat is as Object, without loss of information, or it may use a "fast
- path" which does not use boxing.
-
- Notwithstanding the rules above, for compatibility with the verifier,
- if T is an interface, it is treated as if it were Object. [KEEP THIS?]
-
- Also, for compatibility with the verifier, a boolean may be undergo
- widening or narrowing conversion to any other primitive type. [KEEP THIS?]
- */
-
- /**
- * Produces a method handle which adapts the calling sequence of the
- * given method handle to a new type, by reordering the arguments.
- * The resulting method handle is guaranteed to report a type
- * which is equal to the desired new type.
- *
- * The given array controls the reordering.
- * Call {@code #I} the number of incoming parameters (the value
- * {@code newType.parameterCount()}, and call {@code #O} the number
- * of outgoing parameters (the value {@code target.type().parameterCount()}).
- * Then the length of the reordering array must be {@code #O},
- * and each element must be a non-negative number less than {@code #I}.
- * For every {@code N} less than {@code #O}, the {@code N}-th
- * outgoing argument will be taken from the {@code I}-th incoming
- * argument, where {@code I} is {@code reorder[N]}.
- *
- * No argument or return value conversions are applied.
- * The type of each incoming argument, as determined by {@code newType},
- * must be identical to the type of the corresponding outgoing argument
- * or arguments in the target method handle.
- * The return type of {@code newType} must be identical to the return
- * type of the original target.
- *
- * The reordering array need not specify an actual permutation.
- * An incoming argument will be duplicated if its index appears
- * more than once in the array, and an incoming argument will be dropped
- * if its index does not appear in the array.
- * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
- * incoming arguments which are not mentioned in the reordering array
- * are may be any type, as determined only by {@code newType}.
- *
-MethodType intfn1 = MethodType.methodType(int.class, int.class);
-MethodType intfn2 = MethodType.methodType(int.class, int.class, int.class);
-MethodHandle sub = ... {int x, int y => x-y} ...;
-assert(sub.type().equals(intfn2));
-MethodHandle sub1 = MethodHandles.permuteArguments(sub, intfn2, 0, 1);
-MethodHandle rsub = MethodHandles.permuteArguments(sub, intfn2, 1, 0);
-assert((int)rsub.invokeExact(1, 100) == 99);
-MethodHandle add = ... {int x, int y => x+y} ...;
-assert(add.type().equals(intfn2));
-MethodHandle twice = MethodHandles.permuteArguments(add, intfn1, 0, 0);
-assert(twice.type().equals(intfn1));
-assert((int)twice.invokeExact(21) == 42);
- *
- * @param target the method handle to invoke after arguments are reordered
- * @param newType the expected type of the new method handle
- * @param reorder a string which controls the reordering
- * @return a method handle which delegates to {@code target} after it
- * drops unused arguments and moves and/or duplicates the other arguments
- * @throws NullPointerException if any argument is null
- */
- public static
- MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
- MethodType oldType = target.type();
- checkReorder(reorder, newType, oldType);
- return MethodHandleImpl.convertArguments(IMPL_TOKEN, target,
- newType, oldType,
- reorder);
- }
-
- private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
- if (reorder.length == oldType.parameterCount()) {
- int limit = newType.parameterCount();
- boolean bad = false;
- for (int i : reorder) {
- if (i < 0 || i >= limit) {
- bad = true; break;
- }
- }
- if (!bad) return;
- }
- throw newIllegalArgumentException("bad reorder array");
- }
-
- /**
- * Equivalent to the following code:
- *
- * int spreadPos = newType.parameterCount() - 1;
- * Class<?> spreadType = newType.parameterType(spreadPos);
- * int spreadCount = target.type().parameterCount() - spreadPos;
- * MethodHandle adapter = target.asSpreader(spreadType, spreadCount);
- * adapter = adapter.asType(newType);
- * return adapter;
- *
- * @param target the method handle to invoke after argument spreading
- * @param newType the expected type of the new method handle
- * @return a method handle which spreads its final argument,
- * before calling the original method handle
- */
- /*non-public*/ static
- MethodHandle spreadArguments(MethodHandle target, MethodType newType) {
- MethodType oldType = target.type();
- int inargs = newType.parameterCount();
- int outargs = oldType.parameterCount();
- int spreadPos = inargs - 1;
- int numSpread = (outargs - spreadPos);
- MethodHandle res = null;
- if (spreadPos >= 0 && numSpread >= 0) {
- res = MethodHandleImpl.spreadArguments(IMPL_TOKEN, target, newType, spreadPos);
- }
- if (res == null) {
- throw newIllegalArgumentException("cannot spread "+newType+" to " +oldType);
- }
- return res;
- }
-
- /**
- * Equivalent to the following code:
- *
- * int collectPos = target.type().parameterCount() - 1;
- * Class<?> collectType = target.type().parameterType(collectPos);
- * if (!collectType.isArray()) collectType = Object[].class;
- * int collectCount = newType.parameterCount() - collectPos;
- * MethodHandle adapter = target.asCollector(collectType, collectCount);
- * adapter = adapter.asType(newType);
- * return adapter;
- *
- * @param target the method handle to invoke after argument collection
- * @param newType the expected type of the new method handle
- * @return a method handle which collects some trailing argument
- * into an array, before calling the original method handle
- */
- /*non-public*/ static
- MethodHandle collectArguments(MethodHandle target, MethodType newType) {
- MethodType oldType = target.type();
- int inargs = newType.parameterCount();
- int outargs = oldType.parameterCount();
- int collectPos = outargs - 1;
- int numCollect = (inargs - collectPos);
- if (collectPos < 0 || numCollect < 0)
- throw newIllegalArgumentException("wrong number of arguments");
- MethodHandle res = MethodHandleImpl.collectArguments(IMPL_TOKEN, target, newType, collectPos, null);
- if (res == null) {
- throw newIllegalArgumentException("cannot collect from "+newType+" to " +oldType);
- }
- return res;
- }
-
- /**
- * Produces a method handle of the requested return type which returns the given
- * constant value every time it is invoked.
- *
- * Before the method handle is returned, the passed-in value is converted to the requested type.
- * If the requested type is primitive, widening primitive conversions are attempted,
- * else reference conversions are attempted.
- *
The returned method handle is equivalent to {@code identity(type).bindTo(value)},
- * unless the type is {@code void}, in which case it is {@code identity(type)}.
- * @param type the return type of the desired method handle
- * @param value the value to return
- * @return a method handle of the given return type and no arguments, which always returns the given value
- * @throws NullPointerException if the {@code type} argument is null
- * @throws ClassCastException if the value cannot be converted to the required return type
- * @throws IllegalArgumentException if the given type is {@code void.class}
- */
- public static
- MethodHandle constant(Class> type, Object value) {
- if (type.isPrimitive()) {
- if (type == void.class)
- throw newIllegalArgumentException("void type");
- Wrapper w = Wrapper.forPrimitiveType(type);
- return identity(type).bindTo(w.convert(value, type));
- } else {
- return identity(type).bindTo(type.cast(value));
- }
- }
-
- /**
- * Produces a method handle which returns its sole argument when invoked.
- *
The identity function for {@code void} takes no arguments and returns no values.
- * @param type the type of the sole parameter and return value of the desired method handle
- * @return a unary method handle which accepts and returns the given type
- * @throws NullPointerException if the argument is null
- * @throws IllegalArgumentException if the given type is {@code void.class}
- */
- public static
- MethodHandle identity(Class> type) {
- if (type == void.class)
- throw newIllegalArgumentException("void type");
- return ValueConversions.identity(type);
- }
-
- /**
- * Produces a method handle which calls the original method handle {@code target},
- * after inserting the given argument(s) at the given position.
- * The formal parameters to {@code target} which will be supplied by those
- * arguments are called bound parameters , because the new method
- * will contain bindings for those parameters take from {@code values}.
- * The type of the new method handle will drop the types for the bound
- * parameters from the original target type, since the new method handle
- * will no longer require those arguments to be supplied by its callers.
- *
- * Each given argument object must match the corresponding bound parameter type.
- * If a bound parameter type is a primitive, the argument object
- * must be a wrapper, and will be unboxed to produce the primitive value.
- *
- * The pos may range between zero and N (inclusively),
- * where N is the number of argument types in resulting method handle
- * (after bound parameter types are dropped).
- * @param target the method handle to invoke after the argument is inserted
- * @param pos where to insert the argument (zero for the first)
- * @param values the series of arguments to insert
- * @return a method handle which inserts an additional argument,
- * before calling the original method handle
- * @throws NullPointerException if the {@code target} argument or the {@code values} array is null
- * @see MethodHandle#bindTo
- */
- public static
- MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
- int insCount = values.length;
- MethodType oldType = target.type();
- ArrayList> ptypes =
- new ArrayList>(oldType.parameterList());
- int outargs = oldType.parameterCount();
- int inargs = outargs - insCount;
- if (inargs < 0)
- throw newIllegalArgumentException("too many values to insert");
- if (pos < 0 || pos > inargs)
- throw newIllegalArgumentException("no argument type to append");
- MethodHandle result = target;
- for (int i = 0; i < insCount; i++) {
- Object value = values[i];
- Class> valueType = oldType.parameterType(pos+i);
- value = checkValue(valueType, value);
- if (pos == 0 && !valueType.isPrimitive()) {
- // At least for now, make bound method handles a special case.
- MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, result, value);
- if (bmh != null) {
- result = bmh;
- continue;
- }
- // else fall through to general adapter machinery
- }
- result = MethodHandleImpl.bindArgument(IMPL_TOKEN, result, pos, value);
- }
- return result;
- }
-
- /**
- * Produces a method handle which calls the original method handle,
- * after dropping the given argument(s) at the given position.
- * The type of the new method handle will insert the given argument
- * type(s), at that position, into the original handle's type.
- *
- * The pos may range between zero and N ,
- * where N is the number of argument types in target ,
- * meaning to drop the first or last argument (respectively),
- * or an argument somewhere in between.
- *
- * Example:
- *
-import static java.dyn.MethodHandles.*;
-import static java.dyn.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-assertEquals("xy", (String) cat.invokeExact("x", "y"));
-MethodHandle d0 = dropArguments(cat, 0, String.class);
-assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
-MethodHandle d1 = dropArguments(cat, 1, String.class);
-assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
-MethodHandle d2 = dropArguments(cat, 2, String.class);
-assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
-MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
-assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
- *
- * @param target the method handle to invoke after the arguments are dropped
- * @param valueTypes the type(s) of the argument(s) to drop
- * @param pos position of first argument to drop (zero for the leftmost)
- * @return a method handle which drops arguments of the given types,
- * before calling the original method handle
- * @throws NullPointerException if the {@code target} argument is null,
- * or if the {@code valueTypes} list or any of its elements is null
- * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
- */
- public static
- MethodHandle dropArguments(MethodHandle target, int pos, List> valueTypes) {
- if (valueTypes.size() == 0) return target;
- MethodType oldType = target.type();
- int outargs = oldType.parameterCount();
- int inargs = outargs + valueTypes.size();
- if (pos < 0 || pos >= inargs)
- throw newIllegalArgumentException("no argument type to remove");
- ArrayList> ptypes =
- new ArrayList>(oldType.parameterList());
- ptypes.addAll(pos, valueTypes);
- MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
- return MethodHandleImpl.dropArguments(IMPL_TOKEN, target, newType, pos);
- }
-
- /**
- * Produces a method handle which calls the original method handle,
- * after dropping the given argument(s) at the given position.
- * The type of the new method handle will insert the given argument
- * type(s), at that position, into the original handle's type.
- * This method is equivalent to the following code:
- *
- * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
- *
- * @param target the method handle to invoke after the arguments are dropped
- * @param valueTypes the type(s) of the argument(s) to drop
- * @param pos position of first argument to drop (zero for the leftmost)
- * @return a method handle which drops arguments of the given types,
- * before calling the original method handle
- * @throws NullPointerException if the {@code target} argument is null,
- * or if the {@code valueTypes} array or any of its elements is null
- * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
- */
- public static
- MethodHandle dropArguments(MethodHandle target, int pos, Class>... valueTypes) {
- return dropArguments(target, pos, Arrays.asList(valueTypes));
- }
-
- /**
- * Adapt a target method handle {@code target} by pre-processing
- * one or more of its arguments, each with its own unary filter function,
- * and then calling the target with each pre-processed argument
- * replaced by the result of its corresponding filter function.
- *
- * The pre-processing is performed by one or more method handles,
- * specified in the elements of the {@code filters} array.
- * Null arguments in the array are ignored, and the corresponding arguments left unchanged.
- * (If there are no non-null elements in the array, the original target is returned.)
- * Each filter is applied to the corresponding argument of the adapter.
- *
- * If a filter {@code F} applies to the {@code N}th argument of
- * the method handle, then {@code F} must be a method handle which
- * takes exactly one argument. The type of {@code F}'s sole argument
- * replaces the corresponding argument type of the target
- * in the resulting adapted method handle.
- * The return type of {@code F} must be identical to the corresponding
- * parameter type of the target.
- *
- * It is an error if there are elements of {@code filters}
- * which do not correspond to argument positions in the target.
- * Example:
- *
-import static java.dyn.MethodHandles.*;
-import static java.dyn.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-MethodHandle upcase = lookup().findVirtual(String.class,
- "toUpperCase", methodType(String.class));
-assertEquals("xy", (String) cat.invokeExact("x", "y"));
-MethodHandle f0 = filterArguments(cat, 0, upcase);
-assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
-MethodHandle f1 = filterArguments(cat, 1, upcase);
-assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
-MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
-assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
- *
- *
- * @param target the method handle to invoke after arguments are filtered
- * @param pos the position of the first argument to filter
- * @param filters method handles to call initially on filtered arguments
- * @return method handle which incorporates the specified argument filtering logic
- * @throws NullPointerException if the {@code target} argument is null
- * or if the {@code filters} array is null
- * @throws IllegalArgumentException if a non-null element of {@code filters}
- * does not match a corresponding argument type of {@code target} as described above,
- * or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}
- */
- public static
- MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
- MethodType targetType = target.type();
- MethodHandle adapter = target;
- MethodType adapterType = targetType;
- int maxPos = targetType.parameterCount();
- if (pos + filters.length > maxPos)
- throw newIllegalArgumentException("too many filters");
- int curPos = pos-1; // pre-incremented
- for (MethodHandle filter : filters) {
- curPos += 1;
- if (filter == null) continue; // ignore null elements of filters
- MethodType filterType = filter.type();
- if (filterType.parameterCount() != 1
- || filterType.returnType() != targetType.parameterType(curPos))
- throw newIllegalArgumentException("target and filter types do not match");
- adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0));
- adapter = MethodHandleImpl.filterArgument(IMPL_TOKEN, adapter, curPos, filter);
- }
- MethodType midType = adapter.type();
- if (midType != adapterType)
- adapter = MethodHandleImpl.convertArguments(IMPL_TOKEN, adapter, adapterType, midType, null);
- return adapter;
- }
-
- /**
- * Adapt a target method handle {@code target} by post-processing
- * its return value with a unary filter function.
- *
- * If a filter {@code F} applies to the return value of
- * the target method handle, then {@code F} must be a method handle which
- * takes exactly one argument. The return type of {@code F}
- * replaces the return type of the target
- * in the resulting adapted method handle.
- * The argument type of {@code F} must be identical to the
- * return type of the target.
- * Example:
- *
-import static java.dyn.MethodHandles.*;
-import static java.dyn.MethodType.*;
-...
-MethodHandle cat = lookup().findVirtual(String.class,
- "concat", methodType(String.class, String.class));
-MethodHandle length = lookup().findVirtual(String.class,
- "length", methodType(int.class));
-System.out.println((String) cat.invokeExact("x", "y")); // xy
-MethodHandle f0 = filterReturnValue(cat, length);
-System.out.println((int) f0.invokeExact("x", "y")); // 2
- *
- * @param target the method handle to invoke before filtering the return value
- * @param filter method handle to call on the return value
- * @return method handle which incorporates the specified return value filtering logic
- * @throws NullPointerException if either argument is null
- * @throws IllegalArgumentException if {@code filter}
- * does not match the return type of {@code target} as described above
- */
- public static
- MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
- MethodType targetType = target.type();
- MethodType filterType = filter.type();
- if (filterType.parameterCount() != 1
- || filterType.parameterType(0) != targetType.returnType())
- throw newIllegalArgumentException("target and filter types do not match");
- // result = fold( lambda(retval, arg...) { filter(retval) },
- // lambda( arg...) { target(arg...) } )
- // FIXME: Too many nodes here.
- MethodHandle returner = dropArguments(filter, 1, targetType.parameterList());
- return foldArguments(returner, target);
- }
-
- /**
- * Adapt a target method handle {@code target} by pre-processing
- * some of its arguments, and then calling the target with
- * the result of the pre-processing, plus all original arguments.
- *
- * The pre-processing is performed by a second method handle, the {@code combiner}.
- * The first {@code N} arguments passed to the adapter,
- * are copied to the combiner, which then produces a result.
- * (Here, {@code N} is defined as the parameter count of the adapter.)
- * After this, control passes to the {@code target}, with both the result
- * of the combiner, and all the original incoming arguments.
- *
- * The first argument type of the target must be identical with the
- * return type of the combiner.
- * The resulting adapter is the same type as the target, except that the
- * initial argument type of the target is dropped.
- *
- * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
- * that either the {@code combiner} or {@code target} does not wish to receive.
- * If some of the incoming arguments are destined only for the combiner,
- * consider using {@link MethodHandle#asCollector asCollector} instead, since those
- * arguments will not need to be live on the stack on entry to the
- * target.)
- *
- * The first argument of the target must be identical with the
- * return value of the combiner.
- *
Here is pseudocode for the resulting adapter:
- *
- * // there are N arguments in the A sequence
- * T target(V, A[N]..., B...);
- * V combiner(A...);
- * T adapter(A... a, B... b) {
- * V v = combiner(a...);
- * return target(v, a..., b...);
- * }
- *
- * @param target the method handle to invoke after arguments are combined
- * @param combiner method handle to call initially on the incoming arguments
- * @return method handle which incorporates the specified argument folding logic
- * @throws NullPointerException if either argument is null
- * @throws IllegalArgumentException if the first argument type of
- * {@code target} is not the same as {@code combiner}'s return type,
- * or if the following argument types of {@code target}
- * are not identical with the argument types of {@code combiner}
- */
- public static
- MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
- MethodType targetType = target.type();
- MethodType combinerType = combiner.type();
- int foldArgs = combinerType.parameterCount();
- boolean ok = (targetType.parameterCount() >= 1 + foldArgs);
- if (ok && !combinerType.parameterList().equals(targetType.parameterList().subList(1, foldArgs+1)))
- ok = false;
- if (ok && !combinerType.returnType().equals(targetType.parameterType(0)))
- ok = false;
- if (!ok)
- throw misMatchedTypes("target and combiner types", targetType, combinerType);
- MethodType newType = targetType.dropParameterTypes(0, 1);
- return MethodHandleImpl.foldArguments(IMPL_TOKEN, target, newType, combiner);
- }
-
- /**
- * Make a method handle which adapts a target method handle,
- * by guarding it with a test, a boolean-valued method handle.
- * If the guard fails, a fallback handle is called instead.
- * All three method handles must have the same corresponding
- * argument and return types, except that the return type
- * of the test must be boolean, and the test is allowed
- * to have fewer arguments than the other two method handles.
- * Here is pseudocode for the resulting adapter:
- *
- * boolean test(A...);
- * T target(A...,B...);
- * T fallback(A...,B...);
- * T adapter(A... a,B... b) {
- * if (test(a...))
- * return target(a..., b...);
- * else
- * return fallback(a..., b...);
- * }
- *
- * Note that the test arguments ({@code a...} in the pseudocode) cannot
- * be modified by execution of the test, and so are passed unchanged
- * from the caller to the target or fallback as appropriate.
- * @param test method handle used for test, must return boolean
- * @param target method handle to call if test passes
- * @param fallback method handle to call if test fails
- * @return method handle which incorporates the specified if/then/else logic
- * @throws NullPointerException if any argument is null
- * @throws IllegalArgumentException if {@code test} does not return boolean,
- * or if all three method types do not match (with the return
- * type of {@code test} changed to match that of {@code target}).
- */
- public static
- MethodHandle guardWithTest(MethodHandle test,
- MethodHandle target,
- MethodHandle fallback) {
- MethodType gtype = test.type();
- MethodType ttype = target.type();
- MethodType ftype = fallback.type();
- if (!ttype.equals(ftype))
- throw misMatchedTypes("target and fallback types", ttype, ftype);
- if (gtype.returnType() != boolean.class)
- throw newIllegalArgumentException("guard type is not a predicate "+gtype);
- List> targs = ttype.parameterList();
- List> gargs = gtype.parameterList();
- if (!targs.equals(gargs)) {
- int gpc = gargs.size(), tpc = targs.size();
- if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
- throw misMatchedTypes("target and test types", ttype, gtype);
- test = dropArguments(test, gpc, targs.subList(gpc, tpc));
- gtype = test.type();
- }
- return MethodHandleImpl.makeGuardWithTest(IMPL_TOKEN, test, target, fallback);
- }
-
- static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
- return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
- }
-
- /**
- * Make a method handle which adapts a target method handle,
- * by running it inside an exception handler.
- * If the target returns normally, the adapter returns that value.
- * If an exception matching the specified type is thrown, the fallback
- * handle is called instead on the exception, plus the original arguments.
- *
- * The target and handler must have the same corresponding
- * argument and return types, except that handler may omit trailing arguments
- * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
- * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
- *
Here is pseudocode for the resulting adapter:
- *
- * T target(A..., B...);
- * T handler(ExType, A...);
- * T adapter(A... a, B... b) {
- * try {
- * return target(a..., b...);
- * } catch (ExType ex) {
- * return handler(ex, a...);
- * }
- * }
- *
- * Note that the saved arguments ({@code a...} in the pseudocode) cannot
- * be modified by execution of the target, and so are passed unchanged
- * from the caller to the handler, if the handler is invoked.
- *
- * The target and handler must return the same type, even if the handler
- * always throws. (This might happen, for instance, because the handler
- * is simulating a {@code finally} clause).
- * To create such a throwing handler, compose the handler creation logic
- * with {@link #throwException throwException},
- * in order to create a method handle of the correct return type.
- * @param target method handle to call
- * @param exType the type of exception which the handler will catch
- * @param handler method handle to call if a matching exception is thrown
- * @return method handle which incorporates the specified try/catch logic
- * @throws NullPointerException if any argument is null
- * @throws IllegalArgumentException if {@code handler} does not accept
- * the given exception type, or if the method handle types do
- * not match in their return types and their
- * corresponding parameters
- */
- public static
- MethodHandle catchException(MethodHandle target,
- Class extends Throwable> exType,
- MethodHandle handler) {
- MethodType ttype = target.type();
- MethodType htype = handler.type();
- if (htype.parameterCount() < 1 ||
- !htype.parameterType(0).isAssignableFrom(exType))
- throw newIllegalArgumentException("handler does not accept exception type "+exType);
- if (htype.returnType() != ttype.returnType())
- throw misMatchedTypes("target and handler return types", ttype, htype);
- List> targs = ttype.parameterList();
- List> hargs = htype.parameterList();
- hargs = hargs.subList(1, hargs.size()); // omit leading parameter from handler
- if (!targs.equals(hargs)) {
- int hpc = hargs.size(), tpc = targs.size();
- if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
- throw misMatchedTypes("target and handler types", ttype, htype);
- handler = dropArguments(handler, hpc, hargs.subList(hpc, tpc));
- htype = handler.type();
- }
- return MethodHandleImpl.makeGuardWithCatch(IMPL_TOKEN, target, exType, handler);
- }
-
- /**
- * Produces a method handle which will throw exceptions of the given {@code exType}.
- * The method handle will accept a single argument of {@code exType},
- * and immediately throw it as an exception.
- * The method type will nominally specify a return of {@code returnType}.
- * The return type may be anything convenient: It doesn't matter to the
- * method handle's behavior, since it will never return normally.
- * @return method handle which can throw the given exceptions
- * @throws NullPointerException if either argument is null
- */
- public static
- MethodHandle throwException(Class> returnType, Class extends Throwable> exType) {
- return MethodHandleImpl.throwException(IMPL_TOKEN, MethodType.methodType(returnType, exType));
- }
-
- /**
- * Produces an instance of the given "SAM" interface which redirects
- * its calls to the given method handle.
- *
- * A SAM interface is an interface which declares a single abstract method.
- * When determining the unique abstract method of a SAM interface,
- * the public {@code Object} methods ({@code toString}, {@code equals}, {@code hashCode})
- * are disregarded. For example, {@link java.util.Comparator} is a SAM interface,
- * even though it re-declares the {@code Object.equals} method.
- * Also, if the SAM interface has a supertype,
- * the SAM interface may override an inherited method.
- * Any such overrides are respected, and the method handle will be accessible
- * by either the inherited method or the SAM method.
- * In particular, a {@linkplain java.lang.reflect.Method#isBridge bridge method}
- * may be created if the methods have different return types.
- *
- * The type must be public. No additional access checks are performed.
- *
- * The resulting instance of the required SAM type will respond to
- * invocation of the SAM type's single abstract method by calling
- * the given {@code target} on the incoming arguments,
- * and returning or throwing whatever the {@code target}
- * returns or throws. The invocation will be as if by
- * {@code target.invokeGeneric}.
- * The target's type will be checked before the SAM
- * instance is created, as if by a call to {@code asType},
- * which may result in a {@code WrongMethodTypeException}.
- *
- * The wrapper instance will implement the requested SAM interface
- * and its super-types, but no other SAM types.
- * This means that the SAM instance will not unexpectedly
- * pass an {@code instanceof} test for any unrequested type.
- *
- * Implementation Note:
- * Therefore, each SAM instance must implement a unique SAM type.
- * Implementations may not bundle together
- * multiple SAM types onto single implementation classes
- * in the style of {@link java.awt.AWTEventMulticaster}.
- *
- * The method handle may throw an undeclared exception ,
- * which means any checked exception (or other checked throwable)
- * not declared by the SAM type's single abstract method.
- * If this happens, the throwable will be wrapped in an instance of
- * {@link java.lang.reflect.UndeclaredThrowableException UndeclaredThrowableException}
- * and thrown in that wrapped form.
- *
- * Like {@link java.lang.Integer#valueOf Integer.valueOf},
- * {@code asInstance} is a factory method whose results are defined
- * by their behavior.
- * It is not guaranteed to return a new instance for every call.
- *
- * Future versions of this API may accept additional types,
- * such as abstract classes with single abstract methods.
- * Future versions of this API may also equip wrapper instances
- * with one or more additional public "marker" interfaces.
- *
- * @param target the method handle to invoke from the wrapper
- * @param samType the desired type of the wrapper, a SAM type
- * @return a correctly-typed wrapper for the given {@code target}
- * @throws NullPointerException if either argument is null
- * @throws IllegalArgumentException if the {@code samType} is not a
- * valid argument to this method
- * @throws WrongMethodTypeException if the {@code target} cannot
- * be converted to the type required by the SAM type
- */
- // Other notes to implementors:
- //
- // No stable mapping is promised between the SAM type and
- // the implementation class C. Over time, several implementation
- // classes might be used for the same SAM type.
- //
- // If the implementation is able
- // to prove that a wrapper of the required SAM type
- // has already been created for a given
- // method handle, or for another method handle with the
- // same behavior, the implementation may return that wrapper in place of
- // a new wrapper.
- //
- // This method is designed to apply to common use cases
- // where a single method handle must interoperate with
- // an interface that implements a function-like
- // API. Additional variations, such as SAM classes with
- // private constructors, or interfaces with multiple but related
- // entry points, must be covered by hand-written or automatically
- // generated adapter classes.
- //
- public static
- T asInstance(final MethodHandle target, final Class samType) {
- // POC implementation only; violates the above contract several ways
- final Method sam = getSamMethod(samType);
- if (sam == null)
- throw new IllegalArgumentException("not a SAM type: "+samType.getName());
- MethodType samMT = MethodType.methodType(sam.getReturnType(), sam.getParameterTypes());
- MethodHandle checkTarget = target.asType(samMT); // make throw WMT
- checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
- final MethodHandle vaTarget = checkTarget.asSpreader(Object[].class, samMT.parameterCount());
- return samType.cast(Proxy.newProxyInstance(
- samType.getClassLoader(),
- new Class[]{ samType, WrapperInstance.class },
- new InvocationHandler() {
- private Object getArg(String name) {
- if ((Object)name == "getWrapperInstanceTarget") return target;
- if ((Object)name == "getWrapperInstanceType") return samType;
- throw new AssertionError();
- }
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- if (method.getDeclaringClass() == WrapperInstance.class)
- return getArg(method.getName());
- if (method.equals(sam))
- return vaTarget.invokeExact(args);
- if (isObjectMethod(method))
- return callObjectMethod(this, method, args);
- throw new InternalError();
- }
- }));
- }
-
- /**
- * Determine if the given object was produced by a call to {@link #asInstance asInstance}.
- * @param x any reference
- * @return true if the reference is not null and points to an object produced by {@code asInstance}
- */
- public static
- boolean isWrapperInstance(Object x) {
- return x instanceof WrapperInstance;
- }
-
- private static WrapperInstance asWrapperInstance(Object x) {
- try {
- if (x != null)
- return (WrapperInstance) x;
- } catch (ClassCastException ex) {
- }
- throw new IllegalArgumentException("not a wrapper instance");
- }
-
- /**
- * Produces or recovers a target method handle which is behaviorally
- * equivalent to the SAM method of this wrapper instance.
- * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
- * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
- * @param x any reference
- * @return a method handle implementing the SAM method
- * @throws IllegalArgumentException if the reference x is not to a wrapper instance
- */
- public static
- MethodHandle wrapperInstanceTarget(Object x) {
- return asWrapperInstance(x).getWrapperInstanceTarget();
- }
-
- /**
- * Recover the SAM type for which this wrapper instance was created.
- * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
- * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
- * @param x any reference
- * @return the SAM type for which the wrapper was created
- * @throws IllegalArgumentException if the reference x is not to a wrapper instance
- */
- public static
- Class> wrapperInstanceType(Object x) {
- return asWrapperInstance(x).getWrapperInstanceType();
- }
-
- private static
- boolean isObjectMethod(Method m) {
- switch (m.getName()) {
- case "toString":
- return (m.getReturnType() == String.class
- && m.getParameterTypes().length == 0);
- case "hashCode":
- return (m.getReturnType() == int.class
- && m.getParameterTypes().length == 0);
- case "equals":
- return (m.getReturnType() == boolean.class
- && m.getParameterTypes().length == 1
- && m.getParameterTypes()[0] == Object.class);
- }
- return false;
- }
-
- private static
- Object callObjectMethod(Object self, Method m, Object[] args) {
- assert(isObjectMethod(m)) : m;
- switch (m.getName()) {
- case "toString":
- return self.getClass().getName() + "@" + Integer.toHexString(self.hashCode());
- case "hashCode":
- return System.identityHashCode(self);
- case "equals":
- return (self == args[0]);
- }
- return null;
- }
-
- private static
- Method getSamMethod(Class> samType) {
- Method sam = null;
- for (Method m : samType.getMethods()) {
- int mod = m.getModifiers();
- if (Modifier.isAbstract(mod)) {
- if (sam != null && !isObjectMethod(sam))
- return null; // too many abstract methods
- sam = m;
- }
- }
- if (!samType.isInterface() && getSamConstructor(samType) == null)
- return null; // wrong kind of constructor
- return sam;
- }
-
- private static
- Constructor getSamConstructor(Class> samType) {
- for (Constructor c : samType.getDeclaredConstructors()) {
- if (c.getParameterTypes().length == 0) {
- int mod = c.getModifiers();
- if (Modifier.isPublic(mod) || Modifier.isProtected(mod))
- return c;
- }
- }
- return null;
- }
-
- /*non-public*/
- static MethodHandle asVarargsCollector(MethodHandle target, Class> arrayType) {
- return MethodHandleImpl.asVarargsCollector(IMPL_TOKEN, target, arrayType);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/MethodType.java
--- a/jdk/src/share/classes/java/dyn/MethodType.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,865 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package java.dyn;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import sun.dyn.Access;
-import sun.dyn.Invokers;
-import sun.dyn.MethodHandleImpl;
-import sun.dyn.MethodTypeImpl;
-import sun.dyn.util.BytecodeDescriptor;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-
-/**
- * A method type represents the arguments and return type accepted and
- * returned by a method handle, or the arguments and return type passed
- * and expected by a method handle caller. Method types must be properly
- * matched between a method handle and all its callers,
- * and the JVM's operations enforce this matching at, specifically
- * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
- * and {@link MethodHandle#invokeGeneric MethodHandle.invokeGeneric}, and during execution
- * of {@code invokedynamic} instructions.
- *
- * The structure is a return type accompanied by any number of parameter types.
- * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
- * (For ease of exposition, we treat {@code void} as if it were a type.
- * In fact, it denotes the absence of a return type.)
- *
- * All instances of {@code MethodType} are immutable.
- * Two instances are completely interchangeable if they compare equal.
- * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
- *
- * This type can be created only by factory methods.
- * All factory methods may cache values, though caching is not guaranteed.
- * Some factory methods are static, while others are virtual methods which
- * modify precursor method types, e.g., by changing a selected parameter.
- *
- * Factory methods which operate on groups of parameter types
- * are systematically presented in two versions, so that both Java arrays and
- * Java lists can be used to work with groups of parameter types.
- * The query methods {@code parameterArray} and {@code parameterList}
- * also provide a choice between arrays and lists.
- *
- * {@code MethodType} objects are sometimes derived from bytecode instructions
- * such as {@code invokedynamic}, specifically from the type descriptor strings associated
- * with the instructions in a class file's constant pool.
- *
- * Like classes and strings, method types can also be represented directly
- * in a class file's constant pool as constants.
- * A method type may be loaded by an {@code ldc} instruction which refers
- * to a suitable {@code CONSTANT_MethodType} constant pool entry.
- * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
- * For more details, see the package summary .
- *
- * When the JVM materializes a {@code MethodType} from a descriptor string,
- * all classes named in the descriptor must be accessible, and will be loaded.
- * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
- * This loading may occur at any time before the {@code MethodType} object is first derived.
- * @author John Rose, JSR 292 EG
- */
-public final
-class MethodType implements java.io.Serializable {
- private static final long serialVersionUID = 292L; // {rtype, {ptype...}}
-
- // The rtype and ptypes fields define the structural identity of the method type:
- private final Class> rtype;
- private final Class>[] ptypes;
-
- // The remaining fields are caches of various sorts:
- private MethodTypeForm form; // erased form, plus cached data about primitives
- private MethodType wrapAlt; // alternative wrapped/unwrapped version
- private Invokers invokers; // cache of handy higher-order adapters
-
- private static final Access IMPL_TOKEN = Access.getToken();
-
- // share a cache with a friend in this package
- Invokers getInvokers() { return invokers; }
- void setInvokers(Invokers inv) { invokers = inv; }
-
- static {
- // This hack allows the implementation package special access to
- // the internals of MethodType. In particular, the MTImpl has all sorts
- // of cached information useful to the implementation code.
- MethodTypeImpl.setMethodTypeFriend(IMPL_TOKEN, new MethodTypeImpl.MethodTypeFriend() {
- public Class>[] ptypes(MethodType mt) { return mt.ptypes; }
- public MethodTypeImpl form(MethodType mt) { return mt.form; }
- public void setForm(MethodType mt, MethodTypeImpl form) {
- assert(mt.form == null);
- mt.form = (MethodTypeForm) form;
- }
- public MethodType makeImpl(Class> rtype, Class>[] ptypes, boolean trusted) {
- return MethodType.makeImpl(rtype, ptypes, trusted);
- }
- public MethodTypeImpl newMethodTypeForm(MethodType mt) {
- return new MethodTypeForm(mt);
- }
- public Invokers getInvokers(MethodType mt) { return mt.invokers; }
- public void setInvokers(MethodType mt, Invokers inv) { mt.invokers = inv; }
- });
- }
-
- /**
- * Check the given parameters for validity and store them into the final fields.
- */
- private MethodType(Class> rtype, Class>[] ptypes) {
- checkRtype(rtype);
- checkPtypes(ptypes);
- this.rtype = rtype;
- this.ptypes = ptypes;
- }
-
- private static void checkRtype(Class> rtype) {
- rtype.equals(rtype); // null check
- }
- private static int checkPtype(Class> ptype) {
- ptype.getClass(); //NPE
- if (ptype == void.class)
- throw newIllegalArgumentException("parameter type cannot be void");
- if (ptype == double.class || ptype == long.class) return 1;
- return 0;
- }
- /** Return number of extra slots (count of long/double args). */
- private static int checkPtypes(Class>[] ptypes) {
- int slots = 0;
- for (Class> ptype : ptypes) {
- slots += checkPtype(ptype);
- }
- checkSlotCount(ptypes.length + slots);
- return slots;
- }
- private static void checkSlotCount(int count) {
- if ((count & 0xFF) != count)
- throw newIllegalArgumentException("bad parameter count "+count);
- }
- private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
- if (num instanceof Integer) num = "bad index: "+num;
- return new IndexOutOfBoundsException(num.toString());
- }
-
- static final HashMap internTable
- = new HashMap();
-
- static final Class>[] NO_PTYPES = {};
-
- /**
- * Find or create an instance of the given method type.
- * @param rtype the return type
- * @param ptypes the parameter types
- * @return a method type with the given components
- * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
- * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
- */
- public static
- MethodType methodType(Class> rtype, Class>[] ptypes) {
- return makeImpl(rtype, ptypes, false);
- }
-
- /**
- * Finds or creates a method type with the given components.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * @return a method type with the given components
- * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
- * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
- */
- public static
- MethodType methodType(Class> rtype, List> ptypes) {
- boolean notrust = false; // random List impl. could return evil ptypes array
- return makeImpl(rtype, ptypes.toArray(NO_PTYPES), notrust);
- }
-
- /**
- * Finds or creates a method type with the given components.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * The leading parameter type is prepended to the remaining array.
- * @return a method type with the given components
- * @throws NullPointerException if {@code rtype} or {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is null
- * @throws IllegalArgumentException if {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is {@code void.class}
- */
- public static
- MethodType methodType(Class> rtype, Class> ptype0, Class>... ptypes) {
- Class>[] ptypes1 = new Class>[1+ptypes.length];
- ptypes1[0] = ptype0;
- System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
- return makeImpl(rtype, ptypes1, true);
- }
-
- /**
- * Finds or creates a method type with the given components.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * The resulting method has no parameter types.
- * @return a method type with the given return value
- * @throws NullPointerException if {@code rtype} is null
- */
- public static
- MethodType methodType(Class> rtype) {
- return makeImpl(rtype, NO_PTYPES, true);
- }
-
- /**
- * Finds or creates a method type with the given components.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * The resulting method has the single given parameter type.
- * @return a method type with the given return value and parameter type
- * @throws NullPointerException if {@code rtype} or {@code ptype0} is null
- * @throws IllegalArgumentException if {@code ptype0} is {@code void.class}
- */
- public static
- MethodType methodType(Class> rtype, Class> ptype0) {
- return makeImpl(rtype, new Class>[]{ ptype0 }, true);
- }
-
- /**
- * Finds or creates a method type with the given components.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * The resulting method has the same parameter types as {@code ptypes},
- * and the specified return type.
- * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
- */
- public static
- MethodType methodType(Class> rtype, MethodType ptypes) {
- return makeImpl(rtype, ptypes.ptypes, true);
- }
-
- /**
- * Sole factory method to find or create an interned method type.
- * @param rtype desired return type
- * @param ptypes desired parameter types
- * @param trusted whether the ptypes can be used without cloning
- * @return the unique method type of the desired structure
- */
- private static
- MethodType makeImpl(Class> rtype, Class>[] ptypes, boolean trusted) {
- if (ptypes == null || ptypes.length == 0) {
- ptypes = NO_PTYPES; trusted = true;
- }
- MethodType mt1 = new MethodType(rtype, ptypes);
- MethodType mt0;
- synchronized (internTable) {
- mt0 = internTable.get(mt1);
- if (mt0 != null)
- return mt0;
- }
- if (!trusted)
- // defensively copy the array passed in by the user
- mt1 = new MethodType(rtype, ptypes.clone());
- // promote the object to the Real Thing, and reprobe
- MethodTypeImpl.initForm(IMPL_TOKEN, mt1);
- synchronized (internTable) {
- mt0 = internTable.get(mt1);
- if (mt0 != null)
- return mt0;
- internTable.put(mt1, mt1);
- }
- return mt1;
- }
-
- // Entry point from JVM. TODO: Change the name & signature.
- private static MethodType makeImpl(Class> rtype, Class>[] ptypes,
- boolean ignore1, boolean ignore2) {
- return makeImpl(rtype, ptypes, true);
- }
-
- private static final MethodType[] objectOnlyTypes = new MethodType[20];
-
- /**
- * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * All parameters and the return type will be {@code Object},
- * except the final varargs parameter if any, which will be {@code Object[]}.
- * @param objectArgCount number of parameters (excluding the varargs parameter if any)
- * @param varargs whether there will be a varargs parameter, of type {@code Object[]}
- * @return a totally generic method type, given only its count of parameters and varargs
- * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
- * @see #genericMethodType(int)
- */
- public static
- MethodType genericMethodType(int objectArgCount, boolean varargs) {
- MethodType mt;
- checkSlotCount(objectArgCount);
- int ivarargs = (!varargs ? 0 : 1);
- int ootIndex = objectArgCount*2 + ivarargs;
- if (ootIndex < objectOnlyTypes.length) {
- mt = objectOnlyTypes[ootIndex];
- if (mt != null) return mt;
- }
- Class>[] ptypes = new Class>[objectArgCount + ivarargs];
- Arrays.fill(ptypes, Object.class);
- if (ivarargs != 0) ptypes[objectArgCount] = Object[].class;
- mt = makeImpl(Object.class, ptypes, true);
- if (ootIndex < objectOnlyTypes.length) {
- objectOnlyTypes[ootIndex] = mt; // cache it here also!
- }
- return mt;
- }
-
- /**
- * Finds or creates a method type whose components are all {@code Object}.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * All parameters and the return type will be Object.
- * @param objectArgCount number of parameters
- * @return a totally generic method type, given only its count of parameters
- * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
- * @see #genericMethodType(int, boolean)
- */
- public static
- MethodType genericMethodType(int objectArgCount) {
- return genericMethodType(objectArgCount, false);
- }
-
- /**
- * Finds or creates a method type with a single different parameter type.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * @param num the index (zero-based) of the parameter type to change
- * @param nptype a new parameter type to replace the old one with
- * @return the same type, except with the selected parameter changed
- * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
- * @throws IllegalArgumentException if {@code nptype} is {@code void.class}
- * @throws NullPointerException if {@code nptype} is null
- */
- public MethodType changeParameterType(int num, Class> nptype) {
- if (parameterType(num) == nptype) return this;
- checkPtype(nptype);
- Class>[] nptypes = ptypes.clone();
- nptypes[num] = nptype;
- return makeImpl(rtype, nptypes, true);
- }
-
- /**
- * Finds or creates a method type with additional parameter types.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * @param num the position (zero-based) of the inserted parameter type(s)
- * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
- * @return the same type, except with the selected parameter(s) inserted
- * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
- * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
- * or if the resulting method type would have more than 255 parameter slots
- * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
- */
- public MethodType insertParameterTypes(int num, Class>... ptypesToInsert) {
- int len = ptypes.length;
- if (num < 0 || num > len)
- throw newIndexOutOfBoundsException(num);
- int ins = checkPtypes(ptypesToInsert);
- checkSlotCount(parameterSlotCount() + ptypesToInsert.length + ins);
- int ilen = ptypesToInsert.length;
- if (ilen == 0) return this;
- Class>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+ilen);
- System.arraycopy(nptypes, num, nptypes, num+ilen, len-num);
- System.arraycopy(ptypesToInsert, 0, nptypes, num, ilen);
- return makeImpl(rtype, nptypes, true);
- }
-
- /**
- * Finds or creates a method type with additional parameter types.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
- * @return the same type, except with the selected parameter(s) appended
- * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
- * or if the resulting method type would have more than 255 parameter slots
- * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
- */
- public MethodType appendParameterTypes(Class>... ptypesToInsert) {
- return insertParameterTypes(parameterCount(), ptypesToInsert);
- }
-
- /**
- * Finds or creates a method type with additional parameter types.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * @param num the position (zero-based) of the inserted parameter type(s)
- * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
- * @return the same type, except with the selected parameter(s) inserted
- * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
- * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
- * or if the resulting method type would have more than 255 parameter slots
- * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
- */
- public MethodType insertParameterTypes(int num, List> ptypesToInsert) {
- return insertParameterTypes(num, ptypesToInsert.toArray(NO_PTYPES));
- }
-
- /**
- * Finds or creates a method type with additional parameter types.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
- * @return the same type, except with the selected parameter(s) appended
- * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
- * or if the resulting method type would have more than 255 parameter slots
- * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
- */
- public MethodType appendParameterTypes(List> ptypesToInsert) {
- return insertParameterTypes(parameterCount(), ptypesToInsert);
- }
-
- /**
- * Finds or creates a method type with some parameter types omitted.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * @param start the index (zero-based) of the first parameter type to remove
- * @param end the index (greater than {@code start}) of the first parameter type after not to remove
- * @return the same type, except with the selected parameter(s) removed
- * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
- * or if {@code end} is negative or greater than {@code parameterCount()}
- * or if {@code start} is greater than {@code end}
- */
- public MethodType dropParameterTypes(int start, int end) {
- int len = ptypes.length;
- if (!(0 <= start && start <= end && end <= len))
- throw newIndexOutOfBoundsException("start="+start+" end="+end);
- if (start == end) return this;
- Class>[] nptypes;
- if (start == 0) {
- if (end == len) {
- // drop all parameters
- nptypes = NO_PTYPES;
- } else {
- // drop initial parameter(s)
- nptypes = Arrays.copyOfRange(ptypes, end, len);
- }
- } else {
- if (end == len) {
- // drop trailing parameter(s)
- nptypes = Arrays.copyOfRange(ptypes, 0, start);
- } else {
- int tail = len - end;
- nptypes = Arrays.copyOfRange(ptypes, 0, start + tail);
- System.arraycopy(ptypes, end, nptypes, start, tail);
- }
- }
- return makeImpl(rtype, nptypes, true);
- }
-
- /**
- * Finds or creates a method type with a different return type.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * @param nrtype a return parameter type to replace the old one with
- * @return the same type, except with the return type change
- * @throws NullPointerException if {@code nrtype} is null
- */
- public MethodType changeReturnType(Class> nrtype) {
- if (returnType() == nrtype) return this;
- return makeImpl(nrtype, ptypes, true);
- }
-
- /**
- * Reports if this type contains a primitive argument or return value.
- * The return type {@code void} counts as a primitive.
- * @return true if any of the types are primitives
- */
- public boolean hasPrimitives() {
- return form.hasPrimitives();
- }
-
- /**
- * Reports if this type contains a wrapper argument or return value.
- * Wrappers are types which box primitive values, such as {@link Integer}.
- * The reference type {@code java.lang.Void} counts as a wrapper.
- * @return true if any of the types are wrappers
- */
- public boolean hasWrappers() {
- return unwrap() != this;
- }
-
- /**
- * Erases all reference types to {@code Object}.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * All primitive types (including {@code void}) will remain unchanged.
- * @return a version of the original type with all reference types replaced
- */
- public MethodType erase() {
- return form.erasedType();
- }
-
- /**
- * Converts all types, both reference and primitive, to {@code Object}.
- * Convenience method for {@link #genericMethodType(int) genericMethodType}.
- * The expression {@code type.wrap().erase()} produces the same value
- * as {@code type.generic()}.
- * @return a version of the original type with all types replaced
- */
- public MethodType generic() {
- return genericMethodType(parameterCount());
- }
-
- /**
- * Converts all primitive types to their corresponding wrapper types.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * All reference types (including wrapper types) will remain unchanged.
- * A {@code void} return type is changed to the type {@code java.lang.Void}.
- * The expression {@code type.wrap().erase()} produces the same value
- * as {@code type.generic()}.
- * @return a version of the original type with all primitive types replaced
- */
- public MethodType wrap() {
- return hasPrimitives() ? wrapWithPrims(this) : this;
- }
-
- /**
- * Convert all wrapper types to their corresponding primitive types.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * All primitive types (including {@code void}) will remain unchanged.
- * A return type of {@code java.lang.Void} is changed to {@code void}.
- * @return a version of the original type with all wrapper types replaced
- */
- public MethodType unwrap() {
- MethodType noprims = !hasPrimitives() ? this : wrapWithPrims(this);
- return unwrapWithNoPrims(noprims);
- }
-
- private static MethodType wrapWithPrims(MethodType pt) {
- assert(pt.hasPrimitives());
- MethodType wt = pt.wrapAlt;
- if (wt == null) {
- // fill in lazily
- wt = MethodTypeImpl.canonicalize(pt, MethodTypeImpl.WRAP, MethodTypeImpl.WRAP);
- assert(wt != null);
- pt.wrapAlt = wt;
- }
- return wt;
- }
-
- private static MethodType unwrapWithNoPrims(MethodType wt) {
- assert(!wt.hasPrimitives());
- MethodType uwt = wt.wrapAlt;
- if (uwt == null) {
- // fill in lazily
- uwt = MethodTypeImpl.canonicalize(wt, MethodTypeImpl.UNWRAP, MethodTypeImpl.UNWRAP);
- if (uwt == null)
- uwt = wt; // type has no wrappers or prims at all
- wt.wrapAlt = uwt;
- }
- return uwt;
- }
-
- /**
- * Returns the parameter type at the specified index, within this method type.
- * @param num the index (zero-based) of the desired parameter type
- * @return the selected parameter type
- * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
- */
- public Class> parameterType(int num) {
- return ptypes[num];
- }
- /**
- * Returns the number of parameter types in this method type.
- * @return the number of parameter types
- */
- public int parameterCount() {
- return ptypes.length;
- }
- /**
- * Returns the return type of this method type.
- * @return the return type
- */
- public Class> returnType() {
- return rtype;
- }
-
- /**
- * Presents the parameter types as a list (a convenience method).
- * The list will be immutable.
- * @return the parameter types (as an immutable list)
- */
- public List> parameterList() {
- return Collections.unmodifiableList(Arrays.asList(ptypes));
- }
-
- /**
- * Presents the parameter types as an array (a convenience method).
- * Changes to the array will not result in changes to the type.
- * @return the parameter types (as a fresh copy if necessary)
- */
- public Class>[] parameterArray() {
- return ptypes.clone();
- }
-
- /**
- * Compares the specified object with this type for equality.
- * That is, it returns true if and only if the specified object
- * is also a method type with exactly the same parameters and return type.
- * @param x object to compare
- * @see Object#equals(Object)
- */
- @Override
- public boolean equals(Object x) {
- return this == x || x instanceof MethodType && equals((MethodType)x);
- }
-
- private boolean equals(MethodType that) {
- return this.rtype == that.rtype
- && Arrays.equals(this.ptypes, that.ptypes);
- }
-
- /**
- * Returns the hash code value for this method type.
- * It is defined to be the same as the hashcode of a List
- * whose elements are the return type followed by the
- * parameter types.
- * @return the hash code value for this method type
- * @see Object#hashCode()
- * @see #equals(Object)
- * @see List#hashCode()
- */
- @Override
- public int hashCode() {
- int hashCode = 31 + rtype.hashCode();
- for (Class> ptype : ptypes)
- hashCode = 31*hashCode + ptype.hashCode();
- return hashCode;
- }
-
- /**
- * Returns a string representation of the method type,
- * of the form {@code "(PT0,PT1...)RT"}.
- * The string representation of a method type is a
- * parenthesis enclosed, comma separated list of type names,
- * followed immediately by the return type.
- *
- * Each type is represented by its
- * {@link java.lang.Class#getSimpleName simple name}.
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("(");
- for (int i = 0; i < ptypes.length; i++) {
- if (i > 0) sb.append(",");
- sb.append(ptypes[i].getSimpleName());
- }
- sb.append(")");
- sb.append(rtype.getSimpleName());
- return sb.toString();
- }
-
- /// Queries which have to do with the bytecode architecture
-
- /** Reports the number of JVM stack slots required to invoke a method
- * of this type. Note that (for historic reasons) the JVM requires
- * a second stack slot to pass long and double arguments.
- * So this method returns {@link #parameterCount() parameterCount} plus the
- * number of long and double parameters (if any).
- *
- * This method is included for the benfit of applications that must
- * generate bytecodes that process method handles and invokedynamic.
- * @return the number of JVM stack slots for this type's parameters
- * @deprecated Will be removed for PFD.
- */
- public int parameterSlotCount() {
- return form.parameterSlotCount();
- }
-
- /** Reports the number of JVM stack slots which carry all parameters including and after
- * the given position, which must be in the range of 0 to
- * {@code parameterCount} inclusive. Successive parameters are
- * more shallowly stacked, and parameters are indexed in the bytecodes
- * according to their trailing edge. Thus, to obtain the depth
- * in the outgoing call stack of parameter {@code N}, obtain
- * the {@code parameterSlotDepth} of its trailing edge
- * at position {@code N+1}.
- *
- * Parameters of type {@code long} and {@code double} occupy
- * two stack slots (for historical reasons) and all others occupy one.
- * Therefore, the number returned is the number of arguments
- * including and after the given parameter,
- * plus the number of long or double arguments
- * at or after after the argument for the given parameter.
- *
- * This method is included for the benfit of applications that must
- * generate bytecodes that process method handles and invokedynamic.
- * @param num an index (zero-based, inclusive) within the parameter types
- * @return the index of the (shallowest) JVM stack slot transmitting the
- * given parameter
- * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
- * @deprecated Will be removed for PFD.
- */
- public int parameterSlotDepth(int num) {
- if (num < 0 || num > ptypes.length)
- parameterType(num); // force a range check
- return form.parameterToArgSlot(num-1);
- }
-
- /** Reports the number of JVM stack slots required to receive a return value
- * from a method of this type.
- * If the {@link #returnType() return type} is void, it will be zero,
- * else if the return type is long or double, it will be two, else one.
- *
- * This method is included for the benfit of applications that must
- * generate bytecodes that process method handles and invokedynamic.
- * @return the number of JVM stack slots (0, 1, or 2) for this type's return value
- * @deprecated Will be removed for PFD.
- */
- public int returnSlotCount() {
- return form.returnSlotCount();
- }
-
- /**
- * Find or create an instance of a method type, given the spelling of its bytecode descriptor.
- * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
- * Any class or interface name embedded in the descriptor string
- * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
- * on the given loader (or if it is null, on the system class loader).
- *
- * Note that it is possible to encounter method types which cannot be
- * constructed by this method, because their component types are
- * not all reachable from a common class loader.
- *
- * This method is included for the benfit of applications that must
- * generate bytecodes that process method handles and {@code invokedynamic}.
- * @param descriptor a bytecode-level type descriptor string "(T...)T"
- * @param loader the class loader in which to look up the types
- * @return a method type matching the bytecode-level type descriptor
- * @throws IllegalArgumentException if the string is not well-formed
- * @throws TypeNotPresentException if a named type cannot be found
- */
- public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
- throws IllegalArgumentException, TypeNotPresentException
- {
- List> types = BytecodeDescriptor.parseMethod(descriptor, loader);
- Class> rtype = types.remove(types.size() - 1);
- Class>[] ptypes = types.toArray(NO_PTYPES);
- return makeImpl(rtype, ptypes, true);
- }
-
- /**
- * Produces a bytecode descriptor representation of the method type.
- *
- * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
- * Two distinct classes which share a common name but have different class loaders
- * will appear identical when viewed within descriptor strings.
- *
- * This method is included for the benfit of applications that must
- * generate bytecodes that process method handles and {@code invokedynamic}.
- * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
- * because the latter requires a suitable class loader argument.
- * @return the bytecode type descriptor representation
- */
- public String toMethodDescriptorString() {
- return BytecodeDescriptor.unparse(this);
- }
-
- /// Serialization.
-
- /**
- * There are no serializable fields for {@code MethodType}.
- */
- private static final java.io.ObjectStreamField[] serialPersistentFields = { };
-
- /**
- * Save the {@code MethodType} instance to a stream.
- *
- * @serialData
- * For portability, the serialized format does not refer to named fields.
- * Instead, the return type and parameter type arrays are written directly
- * from the {@code writeObject} method, using two calls to {@code s.writeObject}
- * as follows:
- *
-s.writeObject(this.returnType());
-s.writeObject(this.parameterArray());
- *
- *
- * The deserialized field values are checked as if they were
- * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
- * For example, null values, or {@code void} parameter types,
- * will lead to exceptions during deserialization.
- * @param the stream to write the object to
- */
- private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
- s.defaultWriteObject(); // requires serialPersistentFields to be an empty array
- s.writeObject(returnType());
- s.writeObject(parameterArray());
- }
-
- /**
- * Reconstitute the {@code MethodType} instance from a stream (that is,
- * deserialize it).
- * This instance is a scratch object with bogus final fields.
- * It provides the parameters to the factory method called by
- * {@link #readResolve readResolve}.
- * After that call it is discarded.
- * @param the stream to read the object from
- * @see #MethodType()
- * @see #readResolve
- * @see #writeObject
- */
- private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
- s.defaultReadObject(); // requires serialPersistentFields to be an empty array
-
- Class> returnType = (Class>) s.readObject();
- Class>[] parameterArray = (Class>[]) s.readObject();
-
- // Probably this object will never escape, but let's check
- // the field values now, just to be sure.
- checkRtype(returnType);
- checkPtypes(parameterArray);
-
- parameterArray = parameterArray.clone(); // make sure it is unshared
- MethodType_init(returnType, parameterArray);
- }
-
- /**
- * For serialization only.
- * Sets the final fields to null, pending {@code Unsafe.putObject}.
- */
- private MethodType() {
- this.rtype = null;
- this.ptypes = null;
- }
- private void MethodType_init(Class> rtype, Class>[] ptypes) {
- // In order to communicate these values to readResolve, we must
- // store them into the implementation-specific final fields.
- checkRtype(rtype);
- checkPtypes(ptypes);
- unsafe.putObject(this, rtypeOffset, rtype);
- unsafe.putObject(this, ptypesOffset, ptypes);
- }
-
- // Support for resetting final fields while deserializing
- private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
- private static final long rtypeOffset, ptypesOffset;
- static {
- try {
- rtypeOffset = unsafe.objectFieldOffset
- (MethodType.class.getDeclaredField("rtype"));
- ptypesOffset = unsafe.objectFieldOffset
- (MethodType.class.getDeclaredField("ptypes"));
- } catch (Exception ex) {
- throw new Error(ex);
- }
- }
-
- /**
- * Resolves and initializes a {@code MethodType} object
- * after serialization.
- * @return the fully initialized {@code MethodType} object
- */
- private Object readResolve() {
- // Do not use a trusted path for deserialization:
- //return makeImpl(rtype, ptypes, true);
- // Verify all operands, and make sure ptypes is unshared:
- return methodType(rtype, ptypes);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/MethodTypeForm.java
--- a/jdk/src/share/classes/java/dyn/MethodTypeForm.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, 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.
- */
-
-package java.dyn;
-
-/**
- * TO DO: Temporary shim; remove after refactoring effects are complete in JVM.
- * @author John Rose
- */
-import sun.dyn.MethodTypeImpl;
-
-class MethodTypeForm extends MethodTypeImpl {
-
- MethodTypeForm(MethodType erasedType) {
- super(erasedType);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/MutableCallSite.java
--- a/jdk/src/share/classes/java/dyn/MutableCallSite.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package java.dyn;
-
-import sun.dyn.*;
-import sun.dyn.empty.Empty;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * A {@code MutableCallSite} is a {@link CallSite} whose target variable
- * behaves like an ordinary field.
- * An {@code invokedynamic} instruction linked to a {@code MutableCallSite} delegates
- * all calls to the site's current target.
- * The {@linkplain CallSite#dynamicInvoker dynamic invoker} of a mutable call site
- * also delegates each call to the site's current target.
- *
- * Here is an example of a mutable call site which introduces a
- * state variable into a method handle chain.
- *
-MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
-MethodHandle MH_name = name.dynamicInvoker();
-MethodType MT_str2 = MethodType.methodType(String.class, String.class);
-MethodHandle MH_upcase = MethodHandles.lookup()
- .findVirtual(String.class, "toUpperCase", MT_str2);
-MethodHandle worker1 = MethodHandles.filterReturnValue(MH_name, MH_upcase);
-name.setTarget(MethodHandles.constant(String.class, "Rocky"));
-assertEquals("ROCKY", (String) worker1.invokeExact());
-name.setTarget(MethodHandles.constant(String.class, "Fred"));
-assertEquals("FRED", (String) worker1.invokeExact());
-// (mutation can be continued indefinitely)
- *
- *
- * The same call site may be used in several places at once.
- *
-MethodHandle MH_dear = MethodHandles.lookup()
- .findVirtual(String.class, "concat", MT_str2).bindTo(", dear?");
-MethodHandle worker2 = MethodHandles.filterReturnValue(MH_name, MH_dear);
-assertEquals("Fred, dear?", (String) worker2.invokeExact());
-name.setTarget(MethodHandles.constant(String.class, "Wilma"));
-assertEquals("WILMA", (String) worker1.invokeExact());
-assertEquals("Wilma, dear?", (String) worker2.invokeExact());
- *
- *
- * Non-synchronization of target values:
- * A write to a mutable call site's target does not force other threads
- * to become aware of the updated value. Threads which do not perform
- * suitable synchronization actions relative to the updated call site
- * may cache the old target value and delay their use of the new target
- * value indefinitely.
- * (This is a normal consequence of the Java Memory Model as applied
- * to object fields.)
- *
- * The {@link #syncAll syncAll} operation provides a way to force threads
- * to accept a new target value, even if there is no other synchronization.
- *
- * For target values which will be frequently updated, consider using
- * a {@linkplain VolatileCallSite volatile call site} instead.
- * @author John Rose, JSR 292 EG
- */
-public class MutableCallSite extends CallSite {
- /**
- * Creates a blank call site object with the given method type.
- * The initial target is set to a method handle of the given type
- * which will throw an {@link IllegalStateException} if called.
- *
- * The type of the call site is permanently set to the given type.
- *
- * Before this {@code CallSite} object is returned from a bootstrap method,
- * or invoked in some other manner,
- * it is usually provided with a more useful target method,
- * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
- * @param type the method type that this call site will have
- * @throws NullPointerException if the proposed type is null
- */
- public MutableCallSite(MethodType type) {
- super(type);
- }
-
- /**
- * Creates a call site object with an initial target method handle.
- * The type of the call site is permanently set to the initial target's type.
- * @param target the method handle that will be the initial target of the call site
- * @throws NullPointerException if the proposed target is null
- */
- public MutableCallSite(MethodHandle target) {
- super(target);
- }
-
- /**
- * Returns the target method of the call site, which behaves
- * like a normal field of the {@code MutableCallSite}.
- *
- * The interactions of {@code getTarget} with memory are the same
- * as of a read from an ordinary variable, such as an array element or a
- * non-volatile, non-final field.
- *
- * In particular, the current thread may choose to reuse the result
- * of a previous read of the target from memory, and may fail to see
- * a recent update to the target by another thread.
- *
- * @return the linkage state of this call site, a method handle which can change over time
- * @see #setTarget
- */
- @Override public final MethodHandle getTarget() {
- return target;
- }
-
- /**
- * Updates the target method of this call site, as a normal variable.
- * The type of the new target must agree with the type of the old target.
- *
- * The interactions with memory are the same
- * as of a write to an ordinary variable, such as an array element or a
- * non-volatile, non-final field.
- *
- * In particular, unrelated threads may fail to see the updated target
- * until they perform a read from memory.
- * Stronger guarantees can be created by putting appropriate operations
- * into the bootstrap method and/or the target methods used
- * at any given call site.
- *
- * @param newTarget the new target
- * @throws NullPointerException if the proposed new target is null
- * @throws WrongMethodTypeException if the proposed new target
- * has a method type that differs from the previous target
- * @see #getTarget
- */
- @Override public void setTarget(MethodHandle newTarget) {
- checkTargetChange(this.target, newTarget);
- setTargetNormal(newTarget);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final MethodHandle dynamicInvoker() {
- return makeDynamicInvoker();
- }
-
- /**
- * Performs a synchronization operation on each call site in the given array,
- * forcing all other threads to throw away any cached values previously
- * loaded from the target of any of the call sites.
- *
- * This operation does not reverse any calls that have already started
- * on an old target value.
- * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
- *
- * The overall effect is to force all future readers of each call site's target
- * to accept the most recently stored value.
- * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
- * Conversely, the {@code syncAll} call may block until all readers have
- * (somehow) decached all previous versions of each call site's target.
- *
- * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
- * should generally be performed under some sort of mutual exclusion.
- * Note that reader threads may observe an updated target as early
- * as the {@code setTarget} call that install the value
- * (and before the {@code syncAll} that confirms the value).
- * On the other hand, reader threads may observe previous versions of
- * the target until the {@code syncAll} call returns
- * (and after the {@code setTarget} that attempts to convey the updated version).
- *
- * This operation is likely to be expensive and should be used sparingly.
- * If possible, it should be buffered for batch processing on sets of call sites.
- *
- * If {@code sites} contains a null element,
- * a {@code NullPointerException} will be raised.
- * In this case, some non-null elements in the array may be
- * processed before the method returns abnormally.
- * Which elements these are (if any) is implementation-dependent.
- *
- *
Java Memory Model details
- * In terms of the Java Memory Model, this operation performs a synchronization
- * action which is comparable in effect to the writing of a volatile variable
- * by the current thread, and an eventual volatile read by every other thread
- * that may access one of the affected call sites.
- *
- * The following effects are apparent, for each individual call site {@code S}:
- *
- * A new volatile variable {@code V} is created, and written by the current thread.
- * As defined by the JMM, this write is a global synchronization event.
- * As is normal with thread-local ordering of write events,
- * every action already performed by the current thread is
- * taken to happen before the volatile write to {@code V}.
- * (In some implementations, this means that the current thread
- * performs a global release operation.)
- * Specifically, the write to the current target of {@code S} is
- * taken to happen before the volatile write to {@code V}.
- * The volatile write to {@code V} is placed
- * (in an implementation specific manner)
- * in the global synchronization order.
- * Consider an arbitrary thread {@code T} (other than the current thread).
- * If {@code T} executes a synchronization action {@code A}
- * after the volatile write to {@code V} (in the global synchronization order),
- * it is therefore required to see either the current target
- * of {@code S}, or a later write to that target,
- * if it executes a read on the target of {@code S}.
- * (This constraint is called "synchronization-order consistency".)
- * The JMM specifically allows optimizing compilers to elide
- * reads or writes of variables that are known to be useless.
- * Such elided reads and writes have no effect on the happens-before
- * relation. Regardless of this fact, the volatile {@code V}
- * will not be elided, even though its written value is
- * indeterminate and its read value is not used.
- *
- * Because of the last point, the implementation behaves as if a
- * volatile read of {@code V} were performed by {@code T}
- * immediately after its action {@code A}. In the local ordering
- * of actions in {@code T}, this read happens before any future
- * read of the target of {@code S}. It is as if the
- * implementation arbitrarily picked a read of {@code S}'s target
- * by {@code T}, and forced a read of {@code V} to precede it,
- * thereby ensuring communication of the new target value.
- *
- * As long as the constraints of the Java Memory Model are obeyed,
- * implementations may delay the completion of a {@code syncAll}
- * operation while other threads ({@code T} above) continue to
- * use previous values of {@code S}'s target.
- * However, implementations are (as always) encouraged to avoid
- * livelock, and to eventually require all threads to take account
- * of the updated target.
- *
- *
- * Discussion:
- * For performance reasons, {@code syncAll} is not a virtual method
- * on a single call site, but rather applies to a set of call sites.
- * Some implementations may incur a large fixed overhead cost
- * for processing one or more synchronization operations,
- * but a small incremental cost for each additional call site.
- * In any case, this operation is likely to be costly, since
- * other threads may have to be somehow interrupted
- * in order to make them notice the updated target value.
- * However, it may be observed that a single call to synchronize
- * several sites has the same formal effect as many calls,
- * each on just one of the sites.
- *
- *
- * Implementation Note:
- * Simple implementations of {@code MutableCallSite} may use
- * a volatile variable for the target of a mutable call site.
- * In such an implementation, the {@code syncAll} method can be a no-op,
- * and yet it will conform to the JMM behavior documented above.
- *
- * @param sites an array of call sites to be synchronized
- * @throws NullPointerException if the {@code sites} array reference is null
- * or the array contains a null
- */
- public static void syncAll(MutableCallSite[] sites) {
- if (sites.length == 0) return;
- STORE_BARRIER.lazySet(0);
- for (int i = 0; i < sites.length; i++) {
- sites[i].getClass(); // trigger NPE on first null
- }
- // FIXME: NYI
- }
- private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/SwitchPoint.java
--- a/jdk/src/share/classes/java/dyn/SwitchPoint.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.
- */
-
-package java.dyn;
-
-/**
- *
- * A {@code SwitchPoint} is an object which can publish state transitions to other threads.
- * A switch point is initially in the valid state, but may at any time be
- * changed to the invalid state. Invalidation cannot be reversed.
- * A switch point can combine a guarded pair of method handles into a
- * guarded delegator .
- * The guarded delegator is a method handle which delegates to one of the old method handles.
- * The state of the switch point determines which of the two gets the delegation.
- *
- * A single switch point may be used to control any number of method handles.
- * (Indirectly, therefore, it can control any number of call sites.)
- * This is done by using the single switch point as a factory for combining
- * any number of guarded method handle pairs into guarded delegators.
- *
- * When a guarded delegator is created from a guarded pair, the pair
- * is wrapped in a new method handle {@code M},
- * which is permanently associated with the switch point that created it.
- * Each pair consists of a target {@code T} and a fallback {@code F}.
- * While the switch point is valid, invocations to {@code M} are delegated to {@code T}.
- * After it is invalidated, invocations are delegated to {@code F}.
- *
- * Invalidation is global and immediate, as if the switch point contained a
- * volatile boolean variable consulted on every call to {@code M}.
- * The invalidation is also permanent, which means the switch point
- * can change state only once.
- * The switch point will always delegate to {@code F} after being invalidated.
- * At that point {@code guardWithTest} may ignore {@code T} and return {@code F}.
- *
- * Here is an example of a switch point in action:
- *
-MethodType MT_str2 = MethodType.methodType(String.class, String.class);
-MethodHandle MH_strcat = MethodHandles.lookup()
- .findVirtual(String.class, "concat", MT_str2);
-SwitchPoint spt = new SwitchPoint();
-// the following steps may be repeated to re-use the same switch point:
-MethodHandle worker1 = strcat;
-MethodHandle worker2 = MethodHandles.permuteArguments(strcat, MT_str2, 1, 0);
-MethodHandle worker = spt.guardWithTest(worker1, worker2);
-assertEquals("method", (String) worker.invokeExact("met", "hod"));
-SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });
-assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
- *
- *
- * Discussion:
- * Switch points are useful without subclassing. They may also be subclassed.
- * This may be useful in order to associate application-specific invalidation logic
- * with the switch point.
- *
- * Implementation Note:
- * A switch point behaves as if implemented on top of {@link MutableCallSite},
- * approximately as follows:
- *
-public class SwitchPoint {
- private static final MethodHandle
- K_true = MethodHandles.constant(boolean.class, true),
- K_false = MethodHandles.constant(boolean.class, false);
- private final MutableCallSite mcs;
- private final MethodHandle mcsInvoker;
- public SwitchPoint() {
- this.mcs = new MutableCallSite(K_true);
- this.mcsInvoker = mcs.dynamicInvoker();
- }
- public MethodHandle guardWithTest(
- MethodHandle target, MethodHandle fallback) {
- // Note: mcsInvoker is of type ()boolean.
- // Target and fallback may take any arguments, but must have the same type.
- return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback);
- }
- public static void invalidateAll(SwitchPoint[] spts) {
- List<MutableCallSite> mcss = new ArrayList<>();
- for (SwitchPoint spt : spts) mcss.add(spt.mcs);
- for (MutableCallSite mcs : mcss) mcs.setTarget(K_false);
- MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0]));
- }
-}
- *
- * @author Remi Forax, JSR 292 EG
- */
-public class SwitchPoint {
- private static final MethodHandle
- K_true = MethodHandles.constant(boolean.class, true),
- K_false = MethodHandles.constant(boolean.class, false);
-
- private final MutableCallSite mcs;
- private final MethodHandle mcsInvoker;
-
- /**
- * Creates a new switch point.
- */
- public SwitchPoint() {
- this.mcs = new MutableCallSite(K_true);
- this.mcsInvoker = mcs.dynamicInvoker();
- }
-
- /**
- * Returns a method handle which always delegates either to the target or the fallback.
- * The method handle will delegate to the target exactly as long as the switch point is valid.
- * After that, it will permanently delegate to the fallback.
- *
- * The target and fallback must be of exactly the same method type,
- * and the resulting combined method handle will also be of this type.
- *
- * @param target the method handle selected by the switch point as long as it is valid
- * @param fallback the method handle selected by the switch point after it is invalidated
- * @return a combined method handle which always calls either the target or fallback
- * @throws NullPointerException if either argument is null
- * @see MethodHandles#guardWithTest
- */
- public MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback) {
- if (mcs.getTarget() == K_false)
- return fallback; // already invalid
- return MethodHandles.guardWithTest(mcsInvoker, target, fallback);
- }
-
- /**
- * Sets all of the given switch points into the invalid state.
- * After this call executes, no thread will observe any of the
- * switch points to be in a valid state.
- *
- * This operation is likely to be expensive and should be used sparingly.
- * If possible, it should be buffered for batch processing on sets of switch points.
- *
- * If {@code switchPoints} contains a null element,
- * a {@code NullPointerException} will be raised.
- * In this case, some non-null elements in the array may be
- * processed before the method returns abnormally.
- * Which elements these are (if any) is implementation-dependent.
- *
- *
- * Discussion:
- * For performance reasons, {@code invalidateAll} is not a virtual method
- * on a single switch point, but rather applies to a set of switch points.
- * Some implementations may incur a large fixed overhead cost
- * for processing one or more invalidation operations,
- * but a small incremental cost for each additional invalidation.
- * In any case, this operation is likely to be costly, since
- * other threads may have to be somehow interrupted
- * in order to make them notice the updated switch point state.
- * However, it may be observed that a single call to invalidate
- * several switch points has the same formal effect as many calls,
- * each on just one of the switch points.
- *
- *
- * Implementation Note:
- * Simple implementations of {@code SwitchPoint} may use
- * a private {@link MutableCallSite} to publish the state of a switch point.
- * In such an implementation, the {@code invalidateAll} method can
- * simply change the call site's target, and issue one call to
- * {@linkplain MutableCallSite#syncAll synchronize} all the
- * private call sites.
- *
- * @param switchPoints an array of call sites to be synchronized
- * @throws NullPointerException if the {@code switchPoints} array reference is null
- * or the array contains a null
- */
- public static void invalidateAll(SwitchPoint[] switchPoints) {
- if (switchPoints.length == 0) return;
- MutableCallSite[] sites = new MutableCallSite[switchPoints.length];
- for (int i = 0; i < switchPoints.length; i++) {
- SwitchPoint spt = switchPoints[i];
- if (spt == null) break; // MSC.syncAll will trigger a NPE
- sites[i] = spt.mcs;
- spt.mcs.setTarget(K_false);
- }
- MutableCallSite.syncAll(sites);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/VolatileCallSite.java
--- a/jdk/src/share/classes/java/dyn/VolatileCallSite.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.
- */
-
-package java.dyn;
-
-import java.util.List;
-
-/**
- * A {@code VolatileCallSite} is a {@link CallSite} whose target acts like a volatile variable.
- * An {@code invokedynamic} instruction linked to a {@code VolatileCallSite} sees updates
- * to its call site target immediately, even if the update occurs in another thread.
- * There may be a performance penalty for such tight coupling between threads.
- *
- * Unlike {@code MutableCallSite}, there is no
- * {@linkplain MutableCallSite#syncAll syncAll operation} on volatile
- * call sites, since every write to a volatile variable is implicitly
- * synchronized with reader threads.
- *
- * In other respects, a {@code VolatileCallSite} is interchangeable
- * with {@code MutableCallSite}.
- * @see MutableCallSite
- * @author John Rose, JSR 292 EG
- */
-public class VolatileCallSite extends CallSite {
- /**
- * Creates a call site with a volatile binding to its target.
- * The initial target is set to a method handle
- * of the given type which will throw an {@code IllegalStateException} if called.
- * @param type the method type that this call site will have
- * @throws NullPointerException if the proposed type is null
- */
- public VolatileCallSite(MethodType type) {
- super(type);
- }
-
- /**
- * Creates a call site with a volatile binding to its target.
- * The target is set to the given value.
- * @param target the method handle that will be the initial target of the call site
- * @throws NullPointerException if the proposed target is null
- */
- public VolatileCallSite(MethodHandle target) {
- super(target);
- }
-
- /**
- * Returns the target method of the call site, which behaves
- * like a {@code volatile} field of the {@code VolatileCallSite}.
- *
- * The interactions of {@code getTarget} with memory are the same
- * as of a read from a {@code volatile} field.
- *
- * In particular, the current thread is required to issue a fresh
- * read of the target from memory, and must not fail to see
- * a recent update to the target by another thread.
- *
- * @return the linkage state of this call site, a method handle which can change over time
- * @see #setTarget
- */
- @Override public final MethodHandle getTarget() {
- return getTargetVolatile();
- }
-
- /**
- * Updates the target method of this call site, as a volatile variable.
- * The type of the new target must agree with the type of the old target.
- *
- * The interactions with memory are the same as of a write to a volatile field.
- * In particular, any threads is guaranteed to see the updated target
- * the next time it calls {@code getTarget}.
- * @param newTarget the new target
- * @throws NullPointerException if the proposed new target is null
- * @throws WrongMethodTypeException if the proposed new target
- * has a method type that differs from the previous target
- * @see #getTarget
- */
- @Override public void setTarget(MethodHandle newTarget) {
- checkTargetChange(getTargetVolatile(), newTarget);
- setTargetVolatile(newTarget);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final MethodHandle dynamicInvoker() {
- return makeDynamicInvoker();
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/WrongMethodTypeException.java
--- a/jdk/src/share/classes/java/dyn/WrongMethodTypeException.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.
- */
-
-package java.dyn;
-
-/**
- * Thrown to indicate that code has attempted to call a method handle
- * via the wrong method type. As with the bytecode representation of
- * normal Java method calls, method handle calls are strongly typed
- * to a specific type descriptor associated with a call site.
- *
- * This exception may also be thrown when two method handles are
- * composed, and the system detects that their types cannot be
- * matched up correctly. This amounts to an early evaluation
- * of the type mismatch, at method handle construction time,
- * instead of when the mismatched method handle is called.
- *
- * @author John Rose, JSR 292 EG
- * @since 1.7
- */
-public class WrongMethodTypeException extends RuntimeException {
- private static final long serialVersionUID = 292L;
-
- /**
- * Constructs a {@code WrongMethodTypeException} with no detail message.
- */
- public WrongMethodTypeException() {
- super();
- }
-
- /**
- * Constructs a {@code WrongMethodTypeException} with the specified
- * detail message.
- *
- * @param s the detail message.
- */
- public WrongMethodTypeException(String s) {
- super(s);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/dyn/package-info.java
--- a/jdk/src/share/classes/java/dyn/package-info.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,478 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-/**
- * The {@code java.lang.invoke} package contains dynamic language support provided directly by
- * the Java core class libraries and virtual machine.
- *
- *
- * Historic Note: In some early versions of Java SE 7,
- * the name of this package is {@code java.dyn}.
- *
- * Certain types in this package have special relations to dynamic
- * language support in the virtual machine:
- *
- * The class {@link java.dyn.MethodHandle MethodHandle} contains
- * signature polymorphic methods
- * which can be linked regardless of their type descriptor.
- * Normally, method linkage requires exact matching of type descriptors.
- *
- *
- * The JVM bytecode format supports immediate constants of
- * the classes {@link java.dyn.MethodHandle MethodHandle} and {@link java.dyn.MethodType MethodType}.
- *
- *
- *
- * Corresponding JVM bytecode format changes
- * The following low-level information is presented here as a preview of
- * changes being made to the Java Virtual Machine specification for JSR 292.
- * This information will be incorporated in a future version of the JVM specification.
- *
- * {@code invokedynamic} instruction format
- * In bytecode, an {@code invokedynamic} instruction is formatted as five bytes.
- * The first byte is the opcode 186 (hexadecimal {@code BA}).
- * The next two bytes are a constant pool index (in the same format as for the other {@code invoke} instructions).
- * The final two bytes are reserved for future use and required to be zero.
- * The constant pool reference of an {@code invokedynamic} instruction is to a entry
- * with tag {@code CONSTANT_InvokeDynamic} (decimal 18). See below for its format.
- * The entry specifies the following information:
- *
- * a bootstrap method (a {@link java.dyn.MethodHandle MethodHandle} constant)
- * the dynamic invocation name (a UTF8 string)
- * the argument and return types of the call (encoded as a type descriptor in a UTF8 string)
- * optionally, a sequence of additional static arguments to the bootstrap method ({@code ldc}-type constants)
- *
- *
- * Each instance of an {@code invokedynamic} instruction is called a dynamic call site .
- * Multiple instances of an {@code invokedynamic} instruction can share a single
- * {@code CONSTANT_InvokeDynamic} entry.
- * In any case, distinct call sites always have distinct linkage state.
- *
- * A dynamic call site is originally in an unlinked state. In this state, there is
- * no target method for the call site to invoke.
- * A dynamic call site is linked by means of a bootstrap method,
- * as described below .
- *
- *
- * Historic Note: Some older JVMs may allow the index of a {@code CONSTANT_NameAndType}
- * instead of a {@code CONSTANT_InvokeDynamic}. In earlier, obsolete versions of this API, the
- * bootstrap method was specified dynamically, in a per-class basis, during class initialization.
- *
- *
constant pool entries for {@code invokedynamic} instructions
- * If a constant pool entry has the tag {@code CONSTANT_InvokeDynamic} (decimal 18),
- * it must contain exactly four more bytes after the tag.
- * These bytes are interpreted as two 16-bit indexes, in the usual {@code u2} format.
- * The first pair of bytes after the tag must be an index into a side table called the
- * bootstrap method table , which is stored in the {@code BootstrapMethods}
- * attribute as described below .
- * The second pair of bytes must be an index to a {@code CONSTANT_NameAndType}.
- *
- * The first index specifies a bootstrap method used by the associated dynamic call sites.
- * The second index specifies the method name, argument types, and return type of the dynamic call site.
- * The structure of such an entry is therefore analogous to a {@code CONSTANT_Methodref},
- * except that the bootstrap method specifier reference replaces
- * the {@code CONSTANT_Class} reference of a {@code CONSTANT_Methodref} entry.
- *
- *
constant pool entries for {@linkplain java.dyn.MethodType method types}
- * If a constant pool entry has the tag {@code CONSTANT_MethodType} (decimal 16),
- * it must contain exactly two more bytes, which must be an index to a {@code CONSTANT_Utf8}
- * entry which represents a method type descriptor.
- *
- * The JVM will ensure that on first
- * execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType MethodType}
- * will be created which represents the type descriptor.
- * Any classes mentioned in the {@code MethodType} will be loaded if necessary,
- * but not initialized.
- * Access checking and error reporting is performed exactly as it is for
- * references by {@code ldc} instructions to {@code CONSTANT_Class} constants.
- *
- *
constant pool entries for {@linkplain java.dyn.MethodHandle method handles}
- * If a constant pool entry has the tag {@code CONSTANT_MethodHandle} (decimal 15),
- * it must contain exactly three more bytes. The first byte after the tag is a subtag
- * value which must be in the range 1 through 9, and the last two must be an index to a
- * {@code CONSTANT_Fieldref}, {@code CONSTANT_Methodref}, or
- * {@code CONSTANT_InterfaceMethodref} entry which represents a field or method
- * for which a method handle is to be created.
- * Furthermore, the subtag value and the type of the constant index value
- * must agree according to the table below.
- *
- * The JVM will ensure that on first execution of an {@code ldc} instruction
- * for this entry, a {@link java.dyn.MethodHandle MethodHandle} will be created which represents
- * the field or method reference, according to the specific mode implied by the subtag.
- *
- * As with {@code CONSTANT_Class} and {@code CONSTANT_MethodType} constants,
- * the {@code Class} or {@code MethodType} object which reifies the field or method's
- * type is created. Any classes mentioned in this reification will be loaded if necessary,
- * but not initialized, and access checking and error reporting performed as usual.
- *
- * Unlike the reflective {@code Lookup} API, there are no security manager calls made
- * when these constants are resolved.
- *
- * The method handle itself will have a type and behavior determined by the subtag as follows:
- *
- *
- * N subtag name member MH type bytecode behavior lookup expression
- * 1 REF_getField C.f:T (C)T getfield C.f:T
- * {@linkplain java.dyn.MethodHandles.Lookup#findGetter findGetter(C.class,"f",T.class)}
- * 2 REF_getStatic C.f:T ( )T getstatic C.f:T
- * {@linkplain java.dyn.MethodHandles.Lookup#findStaticGetter findStaticGetter(C.class,"f",T.class)}
- * 3 REF_putField C.f:T (C,T)void putfield C.f:T
- * {@linkplain java.dyn.MethodHandles.Lookup#findSetter findSetter(C.class,"f",T.class)}
- * 4 REF_putStatic C.f:T (T)void putstatic C.f:T
- * {@linkplain java.dyn.MethodHandles.Lookup#findStaticSetter findStaticSetter(C.class,"f",T.class)}
- * 5 REF_invokeVirtual C.m(A*)T (C,A*)T invokevirtual C.m(A*)T
- * {@linkplain java.dyn.MethodHandles.Lookup#findVirtual findVirtual(C.class,"m",MT)}
- * 6 REF_invokeStatic C.m(A*)T (C,A*)T invokestatic C.m(A*)T
- * {@linkplain java.dyn.MethodHandles.Lookup#findStatic findStatic(C.class,"m",MT)}
- * 7 REF_invokeSpecial C.m(A*)T (C,A*)T invokespecial C.m(A*)T
- * {@linkplain java.dyn.MethodHandles.Lookup#findSpecial findSpecial(C.class,"m",MT,this.class)}
- * 8 REF_newInvokeSpecial C.<init>(A*)void (A*)C new C; dup; invokespecial C.<init>(A*)void
- * {@linkplain java.dyn.MethodHandles.Lookup#findConstructor findConstructor(C.class,MT)}
- * 9 REF_invokeInterface C.m(A*)T (C,A*)T invokeinterface C.m(A*)T
- * {@linkplain java.dyn.MethodHandles.Lookup#findVirtual findVirtual(C.class,"m",MT)}
- *
- *
- * Here, the type {@code C} is taken from the {@code CONSTANT_Class} reference associated
- * with the {@code CONSTANT_NameAndType} descriptor.
- * The field name {@code f} or method name {@code m} is taken from the {@code CONSTANT_NameAndType}
- * as is the result type {@code T} and (in the case of a method or constructor) the argument type sequence
- * {@code A*}.
- *
- * Each method handle constant has an equivalent instruction sequence called its bytecode behavior .
- * In general, creating a method handle constant can be done in exactly the same circumstances that
- * the JVM would successfully resolve the symbolic references in the bytecode behavior.
- * Also, the type of a method handle constant is such that a valid {@code invokeExact} call
- * on the method handle has exactly the same JVM stack effects as the bytecode behavior .
- * Finally, calling a method handle constant on a valid set of arguments has exactly the same effect
- * and returns the same result (if any) as the corresponding bytecode behavior .
- *
- * Each method handle constant also has an equivalent reflective lookup expression ,
- * which is a query to a method in {@link java.dyn.MethodHandles.Lookup}.
- * In the example lookup method expression given in the table above, the name {@code MT}
- * stands for a {@code MethodType} built from {@code T} and the sequence of argument types {@code A*}.
- * (Note that the type {@code C} is not prepended to the query type {@code MT} even if the member is non-static.)
- * In the case of {@code findSpecial}, the name {@code this.class} refers to the class containing
- * the bytecodes.
- *
- * The special name {@code } is not allowed.
- * The special name {@code } is not allowed except for subtag 8 as shown.
- *
- * The JVM verifier and linker apply the same access checks and restrictions for these references as for the hypothetical
- * bytecode instructions specified in the last column of the table.
- * A method handle constant will successfully resolve to a method handle if the symbolic references
- * of the corresponding bytecode instruction(s) would also resolve successfully.
- * Otherwise, an attempt to resolve the constant will throw equivalent linkage errors.
- * In particular, method handles to
- * private and protected members can be created in exactly those classes for which the corresponding
- * normal accesses are legal.
- *
- * A constant may refer to a method or constructor with the {@code varargs}
- * bit (hexadecimal {@code 0x0080}) set in its modifier bitmask.
- * The method handle constant produced for such a method behaves as if
- * it were created by {@link java.dyn.MethodHandle#asVarargsCollector asVarargsCollector}.
- * In other words, the constant method handle will exhibit variable arity,
- * when invoked via {@code invokeGeneric}.
- * On the other hand, its behavior with respect to {@code invokeExact} will be the same
- * as if the {@code varargs} bit were not set.
- *
- * Although the {@code CONSTANT_MethodHandle} and {@code CONSTANT_MethodType} constant types
- * resolve class names, they do not force class initialization.
- * Method handle constants for subtags {@code REF_getStatic}, {@code REF_putStatic}, and {@code REF_invokeStatic}
- * may force class initialization on their first invocation, just like the corresponding bytecodes.
- *
- * The rules of section 5.4.3 of the
- * JVM Specification
- * apply to the resolution of {@code CONSTANT_MethodType}, {@code CONSTANT_MethodHandle},
- * and {@code CONSTANT_InvokeDynamic} constants,
- * by the execution of {@code invokedynamic} and {@code ldc} instructions.
- * (Roughly speaking, this means that every use of a constant pool entry
- * must lead to the same outcome.
- * If the resolution succeeds, the same object reference is produced
- * by every subsequent execution of the same instruction.
- * If the resolution of the constant causes an error to occur,
- * the same error will be re-thrown on every subsequent attempt
- * to use this particular constant.)
- *
- * Constants created by the resolution of these constant pool types are not necessarily
- * interned. Except for {@code CONSTANT_Class} and {@code CONSTANT_String} entries,
- * two distinct constant pool entries might not resolve to the same reference
- * even if they contain the same symbolic reference.
- *
- *
Bootstrap Methods
- * Before the JVM can execute a dynamic call site (an {@code invokedynamic} instruction),
- * the call site must first be linked .
- * Linking is accomplished by calling a bootstrap method
- * which is given the static information content of the call site,
- * and which must produce a {@link java.dyn.MethodHandle method handle}
- * that gives the behavior of the call site.
- *
- * Each {@code invokedynamic} instruction statically specifies its own
- * bootstrap method as a constant pool reference.
- * The constant pool reference also specifies the call site's name and type descriptor,
- * just like {@code invokevirtual} and the other invoke instructions.
- *
- * Linking starts with resolving the constant pool entry for the
- * bootstrap method, and resolving a {@link java.dyn.MethodType MethodType} object for
- * the type descriptor of the dynamic call site.
- * This resolution process may trigger class loading.
- * It may therefore throw an error if a class fails to load.
- * This error becomes the abnormal termination of the dynamic
- * call site execution.
- * Linkage does not trigger class initialization.
- *
- * Next, the bootstrap method call is started, with at least four values being stacked:
- *
- * a {@code MethodHandle}, the resolved bootstrap method itself
- * a {@code MethodHandles.Lookup}, a lookup object on the caller class in which dynamic call site occurs
- * a {@code String}, the method name mentioned in the call site
- * a {@code MethodType}, the resolved type descriptor of the call
- * optionally, one or more additional static arguments
- *
- * The method handle is then applied to the other values as if by
- * {@link java.dyn.MethodHandle#invokeGeneric invokeGeneric}.
- * The returned result must be a {@link java.dyn.CallSite CallSite} (or a subclass).
- * The type of the call site's target must be exactly equal to the type
- * derived from the dynamic call site's type descriptor and passed to
- * the bootstrap method.
- * The call site then becomes permanently linked to the dynamic call site.
- *
- * As long as each bootstrap method can be correctly invoked
- * by invokeGeneric
, its detailed type is arbitrary.
- * For example, the first argument could be {@code Object}
- * instead of {@code MethodHandles.Lookup}, and the return type
- * could also be {@code Object} instead of {@code CallSite}.
- *
- * As with any method handle constant, a {@code varargs} modifier bit
- * on the bootstrap method is ignored.
- *
- * Note that the first argument of the bootstrap method cannot be
- * a simple {@code Class} reference. (This is a change from earlier
- * versions of this specification. If the caller class is needed,
- * it is easy to {@linkplain java.dyn.MethodHandles.Lookup#lookupClass() extract it}
- * from the {@code Lookup} object.)
- *
- * After resolution, the linkage process may fail in a variety of ways.
- * All failures are reported by an {@link java.dyn.InvokeDynamicBootstrapError InvokeDynamicBootstrapError},
- * which is thrown as the abnormal termination of the dynamic call
- * site execution.
- * The following circumstances will cause this:
- *
- * the index to the bootstrap method specifier is out of range
- * the bootstrap method cannot be resolved
- * the {@code MethodType} to pass to the bootstrap method cannot be resolved
- * a static argument to the bootstrap method cannot be resolved
- * (i.e., a {@code CONSTANT_Class}, {@code CONSTANT_MethodType},
- * or {@code CONSTANT_MethodHandle} argument cannot be linked)
- * the bootstrap method has the wrong arity,
- * causing {@code invokeGeneric} to throw {@code WrongMethodTypeException}
- * the bootstrap method has a wrong argument or return type
- * the bootstrap method invocation completes abnormally
- * the result from the bootstrap invocation is not a reference to
- * an object of type {@link java.dyn.CallSite CallSite}
- * the target of the {@code CallSite} does not have a target of
- * the expected {@code MethodType}
- *
- *
- * timing of linkage
- * A dynamic call site is linked just before its first execution.
- * The bootstrap method call implementing the linkage occurs within
- * a thread that is attempting a first execution.
- *
- * If there are several such threads, the bootstrap method may be
- * invoked in several threads concurrently.
- * Therefore, bootstrap methods which access global application
- * data must take the usual precautions against race conditions.
- * In any case, every {@code invokedynamic} instruction is either
- * unlinked or linked to a unique {@code CallSite} object.
- *
- * In an application which requires dynamic call sites with individually
- * mutable behaviors, their bootstrap methods should produce distinct
- * {@link java.dyn.CallSite CallSite} objects, one for each linkage request.
- * Alternatively, an application can link a single {@code CallSite} object
- * to several {@code invokedynamic} instructions, in which case
- * a change to the target method will become visible at each of
- * the instructions.
- *
- * If several threads simultaneously execute a bootstrap method for a single dynamic
- * call site, the JVM must choose one {@code CallSite} object and install it visibly to
- * all threads. Any other bootstrap method calls are allowed to complete, but their
- * results are ignored, and their dynamic call site invocations proceed with the originally
- * chosen target object.
- *
- *
- * Historic Note: Unlike some previous versions of this specification,
- * these rules do not enable the JVM to duplicate dynamic call sites,
- * or to issue “causeless” bootstrap method calls.
- * Every dynamic call site transitions at most once from unlinked to linked,
- * just before its first invocation.
- *
- *
- * Each {@code CONSTANT_InvokeDynamic} entry contains an index which references
- * a bootstrap method specifier; all such specifiers are contained in a separate array.
- * This array is defined by a class attribute named {@code BootstrapMethods}.
- * The body of this attribute consists of a sequence of byte pairs, all interpreted as
- * as 16-bit counts or constant pool indexes, in the {@code u2} format.
- * The attribute body starts with a count of bootstrap method specifiers,
- * which is immediately followed by the sequence of specifiers.
- *
- * Each bootstrap method specifier contains an index to a
- * {@code CONSTANT_MethodHandle} constant, which is the bootstrap
- * method itself.
- * This is followed by a count, and then a sequence (perhaps empty) of
- * indexes to additional static arguments
- * for the bootstrap method.
- *
- * During class loading, the verifier must check the structure of the
- * {@code BootstrapMethods} attribute. In particular, each constant
- * pool index must be of the correct type. A bootstrap method index
- * must refer to a {@code CONSTANT_MethodHandle} (tag 15).
- * Every other index must refer to a valid operand of an
- * {@code ldc_w} or {@code ldc2_w} instruction (tag 3..8 or 15..16).
- *
- *
- * An {@code invokedynamic} instruction specifies at least three arguments
- * to pass to its bootstrap method:
- * The caller class (expressed as a {@link java.dyn.MethodHandles.Lookup Lookup object},
- * the name (extracted from the {@code CONSTANT_NameAndType} entry),
- * and the type (also extracted from the {@code CONSTANT_NameAndType} entry).
- * The {@code invokedynamic} instruction may specify additional metadata values
- * to pass to its bootstrap method.
- * Collectively, these values are called static arguments to the
- * {@code invokedynamic} instruction, because they are used once at link
- * time to determine the instruction's behavior on subsequent sets of
- * dynamic arguments .
- *
- * Static arguments are used to communicate application-specific meta-data
- * to the bootstrap method.
- * Drawn from the constant pool, they may include references to classes, method handles,
- * strings, or numeric data that may be relevant to the task of linking that particular call site.
- *
- * Static arguments are specified constant pool indexes stored in the {@code BootstrapMethods} attribute.
- * Before the bootstrap method is invoked, each index is used to compute an {@code Object}
- * reference to the indexed value in the constant pool.
- * The valid constant pool entries are listed in this table:
- *
- *
- * entry type argument type argument value
- * CONSTANT_String java.lang.String
the indexed string literal
- * CONSTANT_Class java.lang.Class
the indexed class, resolved
- * CONSTANT_Integer java.lang.Integer
the indexed int value
- * CONSTANT_Long java.lang.Long
the indexed long value
- * CONSTANT_Float java.lang.Float
the indexed float value
- * CONSTANT_Double java.lang.Double
the indexed double value
- * CONSTANT_MethodHandle java.dyn.MethodHandle
the indexed method handle constant
- * CONSTANT_MethodType java.dyn.MethodType
the indexed method type constant
- *
- *
- *
- * If a given {@code invokedynamic} instruction specifies no static arguments,
- * the instruction's bootstrap method will be invoked on three arguments,
- * conveying the instruction's caller class, name, and method type.
- * If the {@code invokedynamic} instruction specifies one or more static arguments,
- * those values will be passed as additional arguments to the method handle.
- * (Note that because there is a limit of 255 arguments to any method,
- * at most 252 extra arguments can be supplied.)
- * The bootstrap method will be invoked as if by either {@code invokeGeneric}
- * or {@code invokeWithArguments}. (There is no way to tell the difference.)
- *
- * The normal argument conversion rules for {@code invokeGeneric} apply to all stacked arguments.
- * For example, if a pushed value is a primitive type, it may be converted to a reference by boxing conversion.
- * If the bootstrap method is a variable arity method (its modifier bit {@code 0x0080} is set),
- * then some or all of the arguments specified here may be collected into a trailing array parameter.
- * (This is not a special rule, but rather a useful consequence of the interaction
- * between {@code CONSTANT_MethodHandle} constants, the modifier bit for variable arity methods,
- * and the {@code java.dyn.MethodHandle#asVarargsCollector asVarargsCollector} transformation.)
- *
- * Given these rules, here are examples of legal bootstrap method declarations,
- * given various numbers {@code N} of extra arguments.
- * The first rows (marked {@code *}) will work for any number of extra arguments.
- *
- *
- * N sample bootstrap method
- * * CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
- * * CallSite bootstrap(Object... args)
- * * CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs)
- * 0 CallSite bootstrap(Lookup caller, String name, MethodType type)
- * 0 CallSite bootstrap(Lookup caller, Object... nameAndType)
- * 1 CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg)
- * 2 CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
- * 2 CallSite bootstrap(Lookup caller, String name, MethodType type, String... args)
- * 2 CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y)
- *
- *
- * The last example assumes that the extra arguments are of type
- * {@code CONSTANT_String} and {@code CONSTANT_Integer}, respectively.
- * The second-to-last example assumes that all extra arguments are of type
- * {@code CONSTANT_String}.
- * The other examples work with all types of extra arguments.
- *
- * As noted above, the actual method type of the bootstrap method can vary.
- * For example, the fourth argument could be {@code MethodHandle},
- * if that is the type of the corresponding constant in
- * the {@code CONSTANT_InvokeDynamic} entry.
- * In that case, the {@code invokeGeneric} call will pass the extra method handle
- * constant as an {@code Object}, but the type matching machinery of {@code invokeGeneric}
- * will cast the reference back to {@code MethodHandle} before invoking the bootstrap method.
- * (If a string constant were passed instead, by badly generated code, that cast would then fail,
- * resulting in an {@code InvokeDynamicBootstrapError}.)
- *
- * Extra bootstrap method arguments are intended to allow language implementors
- * to safely and compactly encode metadata.
- * In principle, the name and extra arguments are redundant,
- * since each call site could be given its own unique bootstrap method.
- * Such a practice is likely to produce large class files and constant pools.
- *
- *
Structure Summary
- * // summary of constant and attribute structures
-struct CONSTANT_MethodHandle_info {
- u1 tag = 15;
- u1 reference_kind; // 1..8 (one of REF_invokeVirtual, etc.)
- u2 reference_index; // index to CONSTANT_Fieldref or *Methodref
-}
-struct CONSTANT_MethodType_info {
- u1 tag = 16;
- u2 descriptor_index; // index to CONSTANT_Utf8, as in NameAndType
-}
-struct CONSTANT_InvokeDynamic_info {
- u1 tag = 18;
- u2 bootstrap_method_attr_index; // index into BootstrapMethods_attr
- u2 name_and_type_index; // index to CONSTANT_NameAndType, as in Methodref
-}
-struct BootstrapMethods_attr {
- u2 name; // CONSTANT_Utf8 = "BootstrapMethods"
- u4 size;
- u2 bootstrap_method_count;
- struct bootstrap_method_specifier {
- u2 bootstrap_method_ref; // index to CONSTANT_MethodHandle
- u2 bootstrap_argument_count;
- u2 bootstrap_arguments[bootstrap_argument_count]; // constant pool indexes
- } bootstrap_methods[bootstrap_method_count];
-}
- *
- *
- * @author John Rose, JSR 292 EG
- */
-
-package java.dyn;
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/AutoCloseable.java
--- a/jdk/src/share/classes/java/lang/AutoCloseable.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/lang/AutoCloseable.java Wed Jul 05 17:39:17 2017 +0200
@@ -34,12 +34,27 @@
public interface AutoCloseable {
/**
* Closes this resource, relinquishing any underlying resources.
- * This method is invoked automatically by the {@code
- * try}-with-resources statement.
+ * This method is invoked automatically on objects managed by the
+ * {@code try}-with-resources statement.
+ *
+ * While this interface method is declared to throw {@code
+ * Exception}, implementers are strongly encouraged to
+ * declare concrete implementations of the {@code close} method to
+ * throw more specific exceptions, or to throw no exception at all
+ * if the close operation cannot fail.
*
- *
Classes implementing this method are strongly encouraged to
- * be declared to throw more specific exceptions (or no exception
- * at all, if the close cannot fail).
+ *
Implementers of this interface are also strongly advised
+ * to not have the {@code close} method throw {@link
+ * InterruptedException}.
+ *
+ * This exception interacts with a thread's interrupted status,
+ * and runtime misbehavior is likely to occur if an {@code
+ * InterruptedException} is {@linkplain Throwable#addSuppressed
+ * suppressed}.
+ *
+ * More generally, if it would cause problems for an
+ * exception to be suppressed, the {@code AutoCloseable.close}
+ * method should not throw it.
*
*
Note that unlike the {@link java.io.Closeable#close close}
* method of {@link java.io.Closeable}, this {@code close} method
@@ -48,9 +63,8 @@
* visible side effect, unlike {@code Closeable.close} which is
* required to have no effect if called more than once.
*
- * However, while not required to be idempotent, implementers of
- * this interface are strongly encouraged to make their {@code
- * close} methods idempotent.
+ * However, implementers of this interface are strongly encouraged
+ * to make their {@code close} methods idempotent.
*
* @throws Exception if this resource cannot be closed
*/
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/BootstrapMethodError.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/BootstrapMethodError.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang;
+
+/**
+ * Thrown to indicate that an {@code invokedynamic} instruction has
+ * failed to find its bootstrap method,
+ * or the bootstrap method has failed to provide a
+ * {@linkplain java.lang.invoke.CallSite call site} with a {@linkplain java.lang.invoke.CallSite#getTarget target}
+ * of the correct {@linkplain java.lang.invoke.MethodHandle#type method type}.
+ *
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class BootstrapMethodError extends LinkageError {
+ private static final long serialVersionUID = 292L;
+
+ /**
+ * Constructs an {@code BootstrapMethodError} with no detail message.
+ */
+ public BootstrapMethodError() {
+ super();
+ }
+
+ /**
+ * Constructs an {@code BootstrapMethodError} with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public BootstrapMethodError(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a {@code BootstrapMethodError} with the specified
+ * detail message and cause.
+ *
+ * @param s the detail message.
+ * @param cause the cause, may be {@code null}.
+ */
+ public BootstrapMethodError(String s, Throwable cause) {
+ super(s, cause);
+ }
+
+ /**
+ * Constructs a {@code BootstrapMethodError} with the specified
+ * cause.
+ *
+ * @param cause the cause, may be {@code null}.
+ */
+ public BootstrapMethodError(Throwable cause) {
+ // cf. Throwable(Throwable cause) constructor.
+ super(cause == null ? null : cause.toString());
+ initCause(cause);
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/ClassLoader.java
--- a/jdk/src/share/classes/java/lang/ClassLoader.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java Wed Jul 05 17:39:17 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2011, 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
@@ -1626,20 +1626,28 @@
* @since 1.2
*/
protected Package getPackage(String name) {
+ Package pkg;
synchronized (packages) {
- Package pkg = packages.get(name);
- if (pkg == null) {
- if (parent != null) {
- pkg = parent.getPackage(name);
- } else {
- pkg = Package.getSystemPackage(name);
- }
- if (pkg != null) {
- packages.put(name, pkg);
+ pkg = packages.get(name);
+ }
+ if (pkg == null) {
+ if (parent != null) {
+ pkg = parent.getPackage(name);
+ } else {
+ pkg = Package.getSystemPackage(name);
+ }
+ if (pkg != null) {
+ synchronized (packages) {
+ Package pkg2 = packages.get(name);
+ if (pkg2 == null) {
+ packages.put(name, pkg);
+ } else {
+ pkg = pkg2;
+ }
}
}
- return pkg;
}
+ return pkg;
}
/**
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/ClassValue.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/ClassValue.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2010, 2011, 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.
+ */
+
+package java.lang;
+
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Lazily associate a computed value with (potentially) every type.
+ * For example, if a dynamic language needs to construct a message dispatch
+ * table for each class encountered at a message send call site,
+ * it can use a {@code ClassValue} to cache information needed to
+ * perform the message send quickly, for each class encountered.
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public abstract class ClassValue {
+ /**
+ * Computes the given class's derived value for this {@code ClassValue}.
+ *
+ * This method will be invoked within the first thread that accesses
+ * the value with the {@link #get get} method.
+ *
+ * Normally, this method is invoked at most once per class,
+ * but it may be invoked again if there has been a call to
+ * {@link #remove remove}.
+ *
+ * If this method throws an exception, the corresponding call to {@code get}
+ * will terminate abnormally with that exception, and no class value will be recorded.
+ *
+ * @param type the type whose class value must be computed
+ * @return the newly computed value associated with this {@code ClassValue}, for the given class or interface
+ * @see #get
+ * @see #remove
+ */
+ protected abstract T computeValue(Class> type);
+
+ /**
+ * Returns the value for the given class.
+ * If no value has yet been computed, it is obtained by
+ * an invocation of the {@link #computeValue computeValue} method.
+ *
+ * The actual installation of the value on the class
+ * is performed atomically.
+ * At that point, if several racing threads have
+ * computed values, one is chosen, and returned to
+ * all the racing threads.
+ *
+ * The {@code type} parameter is typically a class, but it may be any type,
+ * such as an interface, a primitive type (like {@code int.class}), or {@code void.class}.
+ *
+ * In the absence of {@code remove} calls, a class value has a simple
+ * state diagram: uninitialized and initialized.
+ * When {@code remove} calls are made,
+ * the rules for value observation are more complex.
+ * See the documentation for {@link #remove remove} for more information.
+ *
+ * @param type the type whose class value must be computed or retrieved
+ * @return the current value associated with this {@code ClassValue}, for the given class or interface
+ * @throws NullPointerException if the argument is null
+ * @see #remove
+ * @see #computeValue
+ */
+ public T get(Class> type) {
+ ClassValueMap map = getMap(type);
+ if (map != null) {
+ Object x = map.get(this);
+ if (x != null) {
+ return (T) map.unmaskNull(x);
+ }
+ }
+ return setComputedValue(type);
+ }
+
+ /**
+ * Removes the associated value for the given class.
+ * If this value is subsequently {@linkplain #get read} for the same class,
+ * its value will be reinitialized by invoking its {@link #computeValue computeValue} method.
+ * This may result in an additional invocation of the
+ * {@code computeValue computeValue} method for the given class.
+ *
+ * In order to explain the interaction between {@code get} and {@code remove} calls,
+ * we must model the state transitions of a class value to take into account
+ * the alternation between uninitialized and initialized states.
+ * To do this, number these states sequentially from zero, and note that
+ * uninitialized (or removed) states are numbered with even numbers,
+ * while initialized (or re-initialized) states have odd numbers.
+ *
+ * When a thread {@code T} removes a class value in state {@code 2N},
+ * nothing happens, since the class value is already uninitialized.
+ * Otherwise, the state is advanced atomically to {@code 2N+1}.
+ *
+ * When a thread {@code T} queries a class value in state {@code 2N},
+ * the thread first attempts to initialize the class value to state {@code 2N+1}
+ * by invoking {@code computeValue} and installing the resulting value.
+ *
+ * When {@code T} attempts to install the newly computed value,
+ * if the state is still at {@code 2N}, the class value will be initialized
+ * with the computed value, advancing it to state {@code 2N+1}.
+ *
+ * Otherwise, whether the new state is even or odd,
+ * {@code T} will discard the newly computed value
+ * and retry the {@code get} operation.
+ *
+ * Discarding and retrying is an important proviso,
+ * since otherwise {@code T} could potentially install
+ * a disastrously stale value. For example:
+ *
+ * {@code T} calls {@code CV.get(C)} and sees state {@code 2N}
+ * {@code T} quickly computes a time-dependent value {@code V0} and gets ready to install it
+ * {@code T} is hit by an unlucky paging or scheduling event, and goes to sleep for a long time
+ * ...meanwhile, {@code T2} also calls {@code CV.get(C)} and sees state {@code 2N}
+ * {@code T2} quickly computes a similar time-dependent value {@code V1} and installs it on {@code CV.get(C)}
+ * {@code T2} (or a third thread) then calls {@code CV.remove(C)}, undoing {@code T2}'s work
+ * the previous actions of {@code T2} are repeated several times
+ * also, the relevant computed values change over time: {@code V1}, {@code V2}, ...
+ * ...meanwhile, {@code T} wakes up and attempts to install {@code V0}; this must fail
+ *
+ * We can assume in the above scenario that {@code CV.computeValue} uses locks to properly
+ * observe the time-dependent states as it computes {@code V1}, etc.
+ * This does not remove the threat of a stale value, since there is a window of time
+ * between the return of {@code computeValue} in {@code T} and the installation
+ * of the the new value. No user synchronization is possible during this time.
+ *
+ * @param type the type whose class value must be removed
+ * @throws NullPointerException if the argument is null
+ */
+ public void remove(Class> type) {
+ ClassValueMap map = getMap(type);
+ if (map != null) {
+ synchronized (map) {
+ map.remove(this);
+ }
+ }
+ }
+
+ /// Implementation...
+ // FIXME: Use a data structure here similar that of ThreadLocal (7030453).
+
+ private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+
+ /** Slow path for {@link #get}. */
+ private T setComputedValue(Class> type) {
+ ClassValueMap map = getMap(type);
+ if (map == null) {
+ map = initializeMap(type);
+ }
+ T value = computeValue(type);
+ STORE_BARRIER.lazySet(0);
+ // All stores pending from computeValue are completed.
+ synchronized (map) {
+ // Warm up the table with a null entry.
+ map.preInitializeEntry(this);
+ }
+ STORE_BARRIER.lazySet(0);
+ // All stores pending from table expansion are completed.
+ synchronized (map) {
+ value = (T) map.initializeEntry(this, value);
+ // One might fear a possible race condition here
+ // if the code for map.put has flushed the write
+ // to map.table[*] before the writes to the Map.Entry
+ // are done. This is not possible, since we have
+ // warmed up the table with an empty entry.
+ }
+ return value;
+ }
+
+ // Replace this map by a per-class slot.
+ private static final WeakHashMap, ClassValueMap> ROOT
+ = new WeakHashMap, ClassValueMap>();
+
+ private static ClassValueMap getMap(Class> type) {
+ return ROOT.get(type);
+ }
+
+ private static ClassValueMap initializeMap(Class> type) {
+ synchronized (ClassValue.class) {
+ ClassValueMap map = ROOT.get(type);
+ if (map == null)
+ ROOT.put(type, map = new ClassValueMap());
+ return map;
+ }
+ }
+
+ static class ClassValueMap extends WeakHashMap {
+ /** Make sure this table contains an Entry for the given key, even if it is empty. */
+ void preInitializeEntry(ClassValue key) {
+ if (!this.containsKey(key))
+ this.put(key, null);
+ }
+ /** Make sure this table contains a non-empty Entry for the given key. */
+ Object initializeEntry(ClassValue key, Object value) {
+ Object prior = this.get(key);
+ if (prior != null) {
+ return unmaskNull(prior);
+ }
+ this.put(key, maskNull(value));
+ return value;
+ }
+
+ Object maskNull(Object x) {
+ return x == null ? this : x;
+ }
+ Object unmaskNull(Object x) {
+ return x == this ? null : x;
+ }
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.VerifyType;
+import sun.invoke.util.Wrapper;
+import java.util.Arrays;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * This method handle performs simple conversion or checking of a single argument.
+ * @author jrose
+ */
+class AdapterMethodHandle extends BoundMethodHandle {
+
+ //MethodHandle vmtarget; // next AMH or BMH in chain or final DMH
+ //Object argument; // parameter to the conversion if needed
+ //int vmargslot; // which argument slot is affected
+ private final int conversion; // the type of conversion: RETYPE_ONLY, etc.
+
+ // Constructors in this class *must* be package scoped or private.
+ private AdapterMethodHandle(MethodHandle target, MethodType newType,
+ long conv, Object convArg) {
+ super(newType, convArg, newType.parameterSlotDepth(1+convArgPos(conv)));
+ this.conversion = convCode(conv);
+ // JVM might update VM-specific bits of conversion (ignore)
+ MethodHandleNatives.init(this, target, convArgPos(conv));
+ }
+ private AdapterMethodHandle(MethodHandle target, MethodType newType,
+ long conv) {
+ this(target, newType, conv, null);
+ }
+
+ // TO DO: When adapting another MH with a null conversion, clone
+ // the target and change its type, instead of adding another layer.
+
+ /** Can a JVM-level adapter directly implement the proposed
+ * argument conversions, as if by MethodHandles.convertArguments?
+ */
+ static boolean canPairwiseConvert(MethodType newType, MethodType oldType) {
+ // same number of args, of course
+ int len = newType.parameterCount();
+ if (len != oldType.parameterCount())
+ return false;
+
+ // Check return type. (Not much can be done with it.)
+ Class> exp = newType.returnType();
+ Class> ret = oldType.returnType();
+ if (!VerifyType.isNullConversion(ret, exp))
+ return false;
+
+ // Check args pairwise.
+ for (int i = 0; i < len; i++) {
+ Class> src = newType.parameterType(i); // source type
+ Class> dst = oldType.parameterType(i); // destination type
+ if (!canConvertArgument(src, dst))
+ return false;
+ }
+
+ return true;
+ }
+
+ /** Can a JVM-level adapter directly implement the proposed
+ * argument conversion, as if by MethodHandles.convertArguments?
+ */
+ static boolean canConvertArgument(Class> src, Class> dst) {
+ // ? Retool this logic to use RETYPE_ONLY, CHECK_CAST, etc., as opcodes,
+ // so we don't need to repeat so much decision making.
+ if (VerifyType.isNullConversion(src, dst)) {
+ return true;
+ } else if (src.isPrimitive()) {
+ if (dst.isPrimitive())
+ return canPrimCast(src, dst);
+ else
+ return canBoxArgument(src, dst);
+ } else {
+ if (dst.isPrimitive())
+ return canUnboxArgument(src, dst);
+ else
+ return true; // any two refs can be interconverted
+ }
+ }
+
+ /**
+ * Create a JVM-level adapter method handle to conform the given method
+ * handle to the similar newType, using only pairwise argument conversions.
+ * For each argument, convert incoming argument to the exact type needed.
+ * Only null conversions are allowed on the return value (until
+ * the JVM supports ricochet adapters).
+ * The argument conversions allowed are casting, unboxing,
+ * integral widening or narrowing, and floating point widening or narrowing.
+ * @param newType required call type
+ * @param target original method handle
+ * @return an adapter to the original handle with the desired new type,
+ * or the original target if the types are already identical
+ * or null if the adaptation cannot be made
+ */
+ static MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target) {
+ MethodType oldType = target.type();
+ if (newType == oldType) return target;
+
+ if (!canPairwiseConvert(newType, oldType))
+ return null;
+ // (after this point, it is an assertion error to fail to convert)
+
+ // Find last non-trivial conversion (if any).
+ int lastConv = newType.parameterCount()-1;
+ while (lastConv >= 0) {
+ Class> src = newType.parameterType(lastConv); // source type
+ Class> dst = oldType.parameterType(lastConv); // destination type
+ if (VerifyType.isNullConversion(src, dst)) {
+ --lastConv;
+ } else {
+ break;
+ }
+ }
+ // Now build a chain of one or more adapters.
+ MethodHandle adapter = target;
+ MethodType midType = oldType.changeReturnType(newType.returnType());
+ for (int i = 0; i <= lastConv; i++) {
+ Class> src = newType.parameterType(i); // source type
+ Class> dst = midType.parameterType(i); // destination type
+ if (VerifyType.isNullConversion(src, dst)) {
+ // do nothing: difference is trivial
+ continue;
+ }
+ // Work the current type backward toward the desired caller type:
+ if (i != lastConv) {
+ midType = midType.changeParameterType(i, src);
+ } else {
+ // When doing the last (or only) real conversion,
+ // force all remaining null conversions to happen also.
+ assert(VerifyType.isNullConversion(newType, midType.changeParameterType(i, src)));
+ midType = newType;
+ }
+
+ // Tricky case analysis follows.
+ // It parallels canConvertArgument() above.
+ if (src.isPrimitive()) {
+ if (dst.isPrimitive()) {
+ adapter = makePrimCast(midType, adapter, i, dst);
+ } else {
+ adapter = makeBoxArgument(midType, adapter, i, dst);
+ }
+ } else {
+ if (dst.isPrimitive()) {
+ // Caller has boxed a primitive. Unbox it for the target.
+ // The box type must correspond exactly to the primitive type.
+ // This is simpler than the powerful set of widening
+ // conversions supported by reflect.Method.invoke.
+ // Those conversions require a big nest of if/then/else logic,
+ // which we prefer to make a user responsibility.
+ adapter = makeUnboxArgument(midType, adapter, i, dst);
+ } else {
+ // Simple reference conversion.
+ // Note: Do not check for a class hierarchy relation
+ // between src and dst. In all cases a 'null' argument
+ // will pass the cast conversion.
+ adapter = makeCheckCast(midType, adapter, i, dst);
+ }
+ }
+ assert(adapter != null);
+ assert(adapter.type() == midType);
+ }
+ if (adapter.type() != newType) {
+ // Only trivial conversions remain.
+ adapter = makeRetypeOnly(newType, adapter);
+ assert(adapter != null);
+ // Actually, that's because there were no non-trivial ones:
+ assert(lastConv == -1);
+ }
+ assert(adapter.type() == newType);
+ return adapter;
+ }
+
+ /**
+ * Create a JVM-level adapter method handle to permute the arguments
+ * of the given method.
+ * @param newType required call type
+ * @param target original method handle
+ * @param argumentMap for each target argument, position of its source in newType
+ * @return an adapter to the original handle with the desired new type,
+ * or the original target if the types are already identical
+ * and the permutation is null
+ * @throws IllegalArgumentException if the adaptation cannot be made
+ * directly by a JVM-level adapter, without help from Java code
+ */
+ static MethodHandle makePermutation(MethodType newType, MethodHandle target,
+ int[] argumentMap) {
+ MethodType oldType = target.type();
+ boolean nullPermutation = true;
+ for (int i = 0; i < argumentMap.length; i++) {
+ int pos = argumentMap[i];
+ if (pos != i)
+ nullPermutation = false;
+ if (pos < 0 || pos >= newType.parameterCount()) {
+ argumentMap = new int[0]; break;
+ }
+ }
+ if (argumentMap.length != oldType.parameterCount())
+ throw newIllegalArgumentException("bad permutation: "+Arrays.toString(argumentMap));
+ if (nullPermutation) {
+ MethodHandle res = makePairwiseConvert(newType, target);
+ // well, that was easy
+ if (res == null)
+ throw newIllegalArgumentException("cannot convert pairwise: "+newType);
+ return res;
+ }
+
+ // Check return type. (Not much can be done with it.)
+ Class> exp = newType.returnType();
+ Class> ret = oldType.returnType();
+ if (!VerifyType.isNullConversion(ret, exp))
+ throw newIllegalArgumentException("bad return conversion for "+newType);
+
+ // See if the argument types match up.
+ for (int i = 0; i < argumentMap.length; i++) {
+ int j = argumentMap[i];
+ Class> src = newType.parameterType(j);
+ Class> dst = oldType.parameterType(i);
+ if (!VerifyType.isNullConversion(src, dst))
+ throw newIllegalArgumentException("bad argument #"+j+" conversion for "+newType);
+ }
+
+ // Now figure out a nice mix of SWAP, ROT, DUP, and DROP adapters.
+ // A workable greedy algorithm is as follows:
+ // Drop unused outgoing arguments (right to left: shallowest first).
+ // Duplicate doubly-used outgoing arguments (left to right: deepest first).
+ // Then the remaining problem is a true argument permutation.
+ // Marshal the outgoing arguments as required from left to right.
+ // That is, find the deepest outgoing stack position that does not yet
+ // have the correct argument value, and correct at least that position
+ // by swapping or rotating in the misplaced value (from a shallower place).
+ // If the misplaced value is followed by one or more consecutive values
+ // (also misplaced) issue a rotation which brings as many as possible
+ // into position. Otherwise make progress with either a swap or a
+ // rotation. Prefer the swap as cheaper, but do not use it if it
+ // breaks a slot pair. Prefer the rotation over the swap if it would
+ // preserve more consecutive values shallower than the target position.
+ // When more than one rotation will work (because the required value
+ // is already adjacent to the target position), then use a rotation
+ // which moves the old value in the target position adjacent to
+ // one of its consecutive values. Also, prefer shorter rotation
+ // spans, since they use fewer memory cycles for shuffling.
+
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ private static byte basicType(Class> type) {
+ if (type == null) return T_VOID;
+ switch (Wrapper.forBasicType(type)) {
+ case BOOLEAN: return T_BOOLEAN;
+ case CHAR: return T_CHAR;
+ case FLOAT: return T_FLOAT;
+ case DOUBLE: return T_DOUBLE;
+ case BYTE: return T_BYTE;
+ case SHORT: return T_SHORT;
+ case INT: return T_INT;
+ case LONG: return T_LONG;
+ case OBJECT: return T_OBJECT;
+ case VOID: return T_VOID;
+ }
+ return 99; // T_ILLEGAL or some such
+ }
+
+ /** Number of stack slots for the given type.
+ * Two for T_DOUBLE and T_FLOAT, one for the rest.
+ */
+ private static int type2size(int type) {
+ assert(type >= T_BOOLEAN && type <= T_OBJECT);
+ return (type == T_LONG || type == T_DOUBLE) ? 2 : 1;
+ }
+ private static int type2size(Class> type) {
+ return type2size(basicType(type));
+ }
+
+ /** The given stackMove is the number of slots pushed.
+ * It might be negative. Scale it (multiply) by the
+ * VM's notion of how an address changes with a push,
+ * to get the raw SP change for stackMove.
+ * Then shift and mask it into the correct field.
+ */
+ private static long insertStackMove(int stackMove) {
+ // following variable must be long to avoid sign extension after '<<'
+ long spChange = stackMove * MethodHandleNatives.JVM_STACK_MOVE_UNIT;
+ return (spChange & CONV_STACK_MOVE_MASK) << CONV_STACK_MOVE_SHIFT;
+ }
+
+ /** Construct an adapter conversion descriptor for a single-argument conversion. */
+ private static long makeConv(int convOp, int argnum, int src, int dest) {
+ assert(src == (src & 0xF));
+ assert(dest == (dest & 0xF));
+ assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF);
+ int stackMove = type2size(dest) - type2size(src);
+ return ((long) argnum << 32 |
+ (long) convOp << CONV_OP_SHIFT |
+ (int) src << CONV_SRC_TYPE_SHIFT |
+ (int) dest << CONV_DEST_TYPE_SHIFT |
+ insertStackMove(stackMove)
+ );
+ }
+ private static long makeConv(int convOp, int argnum, int stackMove) {
+ assert(convOp >= OP_DUP_ARGS && convOp <= OP_SPREAD_ARGS);
+ byte src = 0, dest = 0;
+ if (convOp >= OP_COLLECT_ARGS && convOp <= OP_SPREAD_ARGS)
+ src = dest = T_OBJECT;
+ return ((long) argnum << 32 |
+ (long) convOp << CONV_OP_SHIFT |
+ (int) src << CONV_SRC_TYPE_SHIFT |
+ (int) dest << CONV_DEST_TYPE_SHIFT |
+ insertStackMove(stackMove)
+ );
+ }
+ private static long makeSwapConv(int convOp, int srcArg, byte type, int destSlot) {
+ assert(convOp >= OP_SWAP_ARGS && convOp <= OP_ROT_ARGS);
+ return ((long) srcArg << 32 |
+ (long) convOp << CONV_OP_SHIFT |
+ (int) type << CONV_SRC_TYPE_SHIFT |
+ (int) type << CONV_DEST_TYPE_SHIFT |
+ (int) destSlot << CONV_VMINFO_SHIFT
+ );
+ }
+ private static long makeConv(int convOp) {
+ assert(convOp == OP_RETYPE_ONLY || convOp == OP_RETYPE_RAW);
+ return ((long)-1 << 32) | (convOp << CONV_OP_SHIFT); // stackMove, src, dst all zero
+ }
+ private static int convCode(long conv) {
+ return (int)conv;
+ }
+ private static int convArgPos(long conv) {
+ return (int)(conv >>> 32);
+ }
+ private static boolean convOpSupported(int convOp) {
+ assert(convOp >= 0 && convOp <= CONV_OP_LIMIT);
+ return ((1<> CONV_OP_SHIFT; }
+
+ /* Return one plus the position of the first non-trivial difference
+ * between the given types. This is not a symmetric operation;
+ * we are considering adapting the targetType to adapterType.
+ * Trivial differences are those which could be ignored by the JVM
+ * without subverting the verifier. Otherwise, adaptable differences
+ * are ones for which we could create an adapter to make the type change.
+ * Return zero if there are no differences (other than trivial ones).
+ * Return 1+N if N is the only adaptable argument difference.
+ * Return the -2-N where N is the first of several adaptable
+ * argument differences.
+ * Return -1 if there there are differences which are not adaptable.
+ */
+ private static int diffTypes(MethodType adapterType,
+ MethodType targetType,
+ boolean raw) {
+ int diff;
+ diff = diffReturnTypes(adapterType, targetType, raw);
+ if (diff != 0) return diff;
+ int nargs = adapterType.parameterCount();
+ if (nargs != targetType.parameterCount())
+ return -1;
+ diff = diffParamTypes(adapterType, 0, targetType, 0, nargs, raw);
+ //System.out.println("diff "+adapterType);
+ //System.out.println(" "+diff+" "+targetType);
+ return diff;
+ }
+ private static int diffReturnTypes(MethodType adapterType,
+ MethodType targetType,
+ boolean raw) {
+ Class> src = targetType.returnType();
+ Class> dst = adapterType.returnType();
+ if ((!raw
+ ? VerifyType.canPassUnchecked(src, dst)
+ : VerifyType.canPassRaw(src, dst)
+ ) > 0)
+ return 0; // no significant difference
+ if (raw && !src.isPrimitive() && !dst.isPrimitive())
+ return 0; // can force a reference return (very carefully!)
+ //if (false) return 1; // never adaptable!
+ return -1; // some significant difference
+ }
+ private static int diffParamTypes(MethodType adapterType, int astart,
+ MethodType targetType, int tstart,
+ int nargs, boolean raw) {
+ assert(nargs >= 0);
+ int res = 0;
+ for (int i = 0; i < nargs; i++) {
+ Class> src = adapterType.parameterType(astart+i);
+ Class> dest = targetType.parameterType(tstart+i);
+ if ((!raw
+ ? VerifyType.canPassUnchecked(src, dest)
+ : VerifyType.canPassRaw(src, dest)
+ ) <= 0) {
+ // found a difference; is it the only one so far?
+ if (res != 0)
+ return -1-res; // return -2-i for prev. i
+ res = 1+i;
+ }
+ }
+ return res;
+ }
+
+ /** Can a retyping adapter (alone) validly convert the target to newType? */
+ static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
+ return canRetype(newType, targetType, false);
+ }
+ /** Can a retyping adapter (alone) convert the target to newType?
+ * It is allowed to widen subword types and void to int, to make bitwise
+ * conversions between float/int and double/long, and to perform unchecked
+ * reference conversions on return. This last feature requires that the
+ * caller be trusted, and perform explicit cast conversions on return values.
+ */
+ static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
+ return canRetype(newType, targetType, true);
+ }
+ static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) {
+ if (!convOpSupported(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY)) return false;
+ int diff = diffTypes(newType, targetType, raw);
+ // %%% This assert is too strong. Factor diff into VerifyType and reconcile.
+ assert(raw || (diff == 0) == VerifyType.isNullConversion(newType, targetType));
+ return diff == 0;
+ }
+
+ /** Factory method: Performs no conversions; simply retypes the adapter.
+ * Allows unchecked argument conversions pairwise, if they are safe.
+ * Returns null if not possible.
+ */
+ static MethodHandle makeRetypeOnly(MethodType newType, MethodHandle target) {
+ return makeRetype(newType, target, false);
+ }
+ static MethodHandle makeRetypeRaw(MethodType newType, MethodHandle target) {
+ return makeRetype(newType, target, true);
+ }
+ static MethodHandle makeRetype(MethodType newType, MethodHandle target, boolean raw) {
+ MethodType oldType = target.type();
+ if (oldType == newType) return target;
+ if (!canRetype(newType, oldType, raw))
+ return null;
+ // TO DO: clone the target guy, whatever he is, with new type.
+ return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
+ }
+
+ static MethodHandle makeVarargsCollector(MethodHandle target, Class> arrayType) {
+ return new AsVarargsCollector(target, arrayType);
+ }
+
+ static class AsVarargsCollector extends AdapterMethodHandle {
+ final MethodHandle target;
+ final Class> arrayType;
+ MethodHandle cache;
+
+ AsVarargsCollector(MethodHandle target, Class> arrayType) {
+ super(target, target.type(), makeConv(OP_RETYPE_ONLY));
+ this.target = target;
+ this.arrayType = arrayType;
+ this.cache = target.asCollector(arrayType, 0);
+ }
+
+ @Override
+ public boolean isVarargsCollector() {
+ return true;
+ }
+
+ @Override
+ public MethodHandle asType(MethodType newType) {
+ MethodType type = this.type();
+ int collectArg = type.parameterCount() - 1;
+ int newArity = newType.parameterCount();
+ if (newArity == collectArg+1 &&
+ type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
+ // if arity and trailing parameter are compatible, do normal thing
+ return super.asType(newType);
+ }
+ // check cache
+ if (cache.type().parameterCount() == newArity)
+ return cache.asType(newType);
+ // build and cache a collector
+ int arrayLength = newArity - collectArg;
+ MethodHandle collector;
+ try {
+ collector = target.asCollector(arrayType, arrayLength);
+ } catch (IllegalArgumentException ex) {
+ throw new WrongMethodTypeException("cannot build collector");
+ }
+ cache = collector;
+ return collector.asType(newType);
+ }
+
+ @Override
+ public MethodHandle asVarargsCollector(Class> arrayType) {
+ MethodType type = this.type();
+ if (type.parameterType(type.parameterCount()-1) == arrayType)
+ return this;
+ return super.asVarargsCollector(arrayType);
+ }
+ }
+
+ /** Can a checkcast adapter validly convert the target to newType?
+ * The JVM supports all kind of reference casts, even silly ones.
+ */
+ static boolean canCheckCast(MethodType newType, MethodType targetType,
+ int arg, Class> castType) {
+ if (!convOpSupported(OP_CHECK_CAST)) return false;
+ Class> src = newType.parameterType(arg);
+ Class> dst = targetType.parameterType(arg);
+ if (!canCheckCast(src, castType)
+ || !VerifyType.isNullConversion(castType, dst))
+ return false;
+ int diff = diffTypes(newType, targetType, false);
+ return (diff == arg+1); // arg is sole non-trivial diff
+ }
+ /** Can an primitive conversion adapter validly convert src to dst? */
+ static boolean canCheckCast(Class> src, Class> dst) {
+ return (!src.isPrimitive() && !dst.isPrimitive());
+ }
+
+ /** Factory method: Forces a cast at the given argument.
+ * The castType is the target of the cast, and can be any type
+ * with a null conversion to the corresponding target parameter.
+ * Return null if this cannot be done.
+ */
+ static MethodHandle makeCheckCast(MethodType newType, MethodHandle target,
+ int arg, Class> castType) {
+ if (!canCheckCast(newType, target.type(), arg, castType))
+ return null;
+ long conv = makeConv(OP_CHECK_CAST, arg, T_OBJECT, T_OBJECT);
+ return new AdapterMethodHandle(target, newType, conv, castType);
+ }
+
+ /** Can an primitive conversion adapter validly convert the target to newType?
+ * The JVM currently supports all conversions except those between
+ * floating and integral types.
+ */
+ static boolean canPrimCast(MethodType newType, MethodType targetType,
+ int arg, Class> convType) {
+ if (!convOpSupported(OP_PRIM_TO_PRIM)) return false;
+ Class> src = newType.parameterType(arg);
+ Class> dst = targetType.parameterType(arg);
+ if (!canPrimCast(src, convType)
+ || !VerifyType.isNullConversion(convType, dst))
+ return false;
+ int diff = diffTypes(newType, targetType, false);
+ return (diff == arg+1); // arg is sole non-trivial diff
+ }
+ /** Can an primitive conversion adapter validly convert src to dst? */
+ static boolean canPrimCast(Class> src, Class> dst) {
+ if (src == dst || !src.isPrimitive() || !dst.isPrimitive()) {
+ return false;
+ } else if (Wrapper.forPrimitiveType(dst).isFloating()) {
+ // both must be floating types
+ return Wrapper.forPrimitiveType(src).isFloating();
+ } else {
+ // both are integral, and all combinations work fine
+ assert(Wrapper.forPrimitiveType(src).isIntegral() &&
+ Wrapper.forPrimitiveType(dst).isIntegral());
+ return true;
+ }
+ }
+
+ /** Factory method: Truncate the given argument with zero or sign extension,
+ * and/or convert between single and doubleword versions of integer or float.
+ * The convType is the target of the conversion, and can be any type
+ * with a null conversion to the corresponding target parameter.
+ * Return null if this cannot be done.
+ */
+ static MethodHandle makePrimCast(MethodType newType, MethodHandle target,
+ int arg, Class> convType) {
+ MethodType oldType = target.type();
+ if (!canPrimCast(newType, oldType, arg, convType))
+ return null;
+ Class> src = newType.parameterType(arg);
+ long conv = makeConv(OP_PRIM_TO_PRIM, arg, basicType(src), basicType(convType));
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+
+ /** Can an unboxing conversion validly convert src to dst?
+ * The JVM currently supports all kinds of casting and unboxing.
+ * The convType is the unboxed type; it can be either a primitive or wrapper.
+ */
+ static boolean canUnboxArgument(MethodType newType, MethodType targetType,
+ int arg, Class> convType) {
+ if (!convOpSupported(OP_REF_TO_PRIM)) return false;
+ Class> src = newType.parameterType(arg);
+ Class> dst = targetType.parameterType(arg);
+ Class> boxType = Wrapper.asWrapperType(convType);
+ convType = Wrapper.asPrimitiveType(convType);
+ if (!canCheckCast(src, boxType)
+ || boxType == convType
+ || !VerifyType.isNullConversion(convType, dst))
+ return false;
+ int diff = diffTypes(newType, targetType, false);
+ return (diff == arg+1); // arg is sole non-trivial diff
+ }
+ /** Can an primitive unboxing adapter validly convert src to dst? */
+ static boolean canUnboxArgument(Class> src, Class> dst) {
+ return (!src.isPrimitive() && Wrapper.asPrimitiveType(dst).isPrimitive());
+ }
+
+ /** Factory method: Unbox the given argument.
+ * Return null if this cannot be done.
+ */
+ static MethodHandle makeUnboxArgument(MethodType newType, MethodHandle target,
+ int arg, Class> convType) {
+ MethodType oldType = target.type();
+ Class> src = newType.parameterType(arg);
+ Class> dst = oldType.parameterType(arg);
+ Class> boxType = Wrapper.asWrapperType(convType);
+ Class> primType = Wrapper.asPrimitiveType(convType);
+ if (!canUnboxArgument(newType, oldType, arg, convType))
+ return null;
+ MethodType castDone = newType;
+ if (!VerifyType.isNullConversion(src, boxType))
+ castDone = newType.changeParameterType(arg, boxType);
+ long conv = makeConv(OP_REF_TO_PRIM, arg, T_OBJECT, basicType(primType));
+ MethodHandle adapter = new AdapterMethodHandle(target, castDone, conv, boxType);
+ if (castDone == newType)
+ return adapter;
+ return makeCheckCast(newType, adapter, arg, boxType);
+ }
+
+ /** Can an primitive boxing adapter validly convert src to dst? */
+ static boolean canBoxArgument(Class> src, Class> dst) {
+ if (!convOpSupported(OP_PRIM_TO_REF)) return false;
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ /** Factory method: Unbox the given argument.
+ * Return null if this cannot be done.
+ */
+ static MethodHandle makeBoxArgument(MethodType newType, MethodHandle target,
+ int arg, Class> convType) {
+ // this is difficult to do in the JVM because it must GC
+ return null;
+ }
+
+ /** Can an adapter simply drop arguments to convert the target to newType? */
+ static boolean canDropArguments(MethodType newType, MethodType targetType,
+ int dropArgPos, int dropArgCount) {
+ if (dropArgCount == 0)
+ return canRetypeOnly(newType, targetType);
+ if (!convOpSupported(OP_DROP_ARGS)) return false;
+ if (diffReturnTypes(newType, targetType, false) != 0)
+ return false;
+ int nptypes = newType.parameterCount();
+ // parameter types must be the same up to the drop point
+ if (dropArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, dropArgPos, false) != 0)
+ return false;
+ int afterPos = dropArgPos + dropArgCount;
+ int afterCount = nptypes - afterPos;
+ if (dropArgPos < 0 || dropArgPos >= nptypes ||
+ dropArgCount < 1 || afterPos > nptypes ||
+ targetType.parameterCount() != nptypes - dropArgCount)
+ return false;
+ // parameter types after the drop point must also be the same
+ if (afterCount != 0 && diffParamTypes(newType, afterPos, targetType, dropArgPos, afterCount, false) != 0)
+ return false;
+ return true;
+ }
+
+ /** Factory method: Drop selected arguments.
+ * Allow unchecked retyping of remaining arguments, pairwise.
+ * Return null if this is not possible.
+ */
+ static MethodHandle makeDropArguments(MethodType newType, MethodHandle target,
+ int dropArgPos, int dropArgCount) {
+ if (dropArgCount == 0)
+ return makeRetypeOnly(newType, target);
+ if (!canDropArguments(newType, target.type(), dropArgPos, dropArgCount))
+ return null;
+ // in arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ]
+ // out arglist: [0: ...keep1 | dpos: keep2... ]
+ int keep2InPos = dropArgPos + dropArgCount;
+ int dropSlot = newType.parameterSlotDepth(keep2InPos);
+ int keep1InSlot = newType.parameterSlotDepth(dropArgPos);
+ int slotCount = keep1InSlot - dropSlot;
+ assert(slotCount >= dropArgCount);
+ assert(target.type().parameterSlotCount() + slotCount == newType.parameterSlotCount());
+ long conv = makeConv(OP_DROP_ARGS, dropArgPos + dropArgCount - 1, -slotCount);
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+
+ /** Can an adapter duplicate an argument to convert the target to newType? */
+ static boolean canDupArguments(MethodType newType, MethodType targetType,
+ int dupArgPos, int dupArgCount) {
+ if (!convOpSupported(OP_DUP_ARGS)) return false;
+ if (diffReturnTypes(newType, targetType, false) != 0)
+ return false;
+ int nptypes = newType.parameterCount();
+ if (dupArgCount < 0 || dupArgPos + dupArgCount > nptypes)
+ return false;
+ if (targetType.parameterCount() != nptypes + dupArgCount)
+ return false;
+ // parameter types must be the same up to the duplicated arguments
+ if (diffParamTypes(newType, 0, targetType, 0, nptypes, false) != 0)
+ return false;
+ // duplicated types must be, well, duplicates
+ if (diffParamTypes(newType, dupArgPos, targetType, nptypes, dupArgCount, false) != 0)
+ return false;
+ return true;
+ }
+
+ /** Factory method: Duplicate the selected argument.
+ * Return null if this is not possible.
+ */
+ static MethodHandle makeDupArguments(MethodType newType, MethodHandle target,
+ int dupArgPos, int dupArgCount) {
+ if (!canDupArguments(newType, target.type(), dupArgPos, dupArgCount))
+ return null;
+ if (dupArgCount == 0)
+ return target;
+ // in arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... ]
+ // out arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... | dup... ]
+ int keep2InPos = dupArgPos + dupArgCount;
+ int dupSlot = newType.parameterSlotDepth(keep2InPos);
+ int keep1InSlot = newType.parameterSlotDepth(dupArgPos);
+ int slotCount = keep1InSlot - dupSlot;
+ assert(target.type().parameterSlotCount() - slotCount == newType.parameterSlotCount());
+ long conv = makeConv(OP_DUP_ARGS, dupArgPos + dupArgCount - 1, slotCount);
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+
+ /** Can an adapter swap two arguments to convert the target to newType? */
+ static boolean canSwapArguments(MethodType newType, MethodType targetType,
+ int swapArg1, int swapArg2) {
+ if (!convOpSupported(OP_SWAP_ARGS)) return false;
+ if (diffReturnTypes(newType, targetType, false) != 0)
+ return false;
+ if (swapArg1 >= swapArg2) return false; // caller resp
+ int nptypes = newType.parameterCount();
+ if (targetType.parameterCount() != nptypes)
+ return false;
+ if (swapArg1 < 0 || swapArg2 >= nptypes)
+ return false;
+ if (diffParamTypes(newType, 0, targetType, 0, swapArg1, false) != 0)
+ return false;
+ if (diffParamTypes(newType, swapArg1, targetType, swapArg2, 1, false) != 0)
+ return false;
+ if (diffParamTypes(newType, swapArg1+1, targetType, swapArg1+1, swapArg2-swapArg1-1, false) != 0)
+ return false;
+ if (diffParamTypes(newType, swapArg2, targetType, swapArg1, 1, false) != 0)
+ return false;
+ if (diffParamTypes(newType, swapArg2+1, targetType, swapArg2+1, nptypes-swapArg2-1, false) != 0)
+ return false;
+ return true;
+ }
+
+ /** Factory method: Swap the selected arguments.
+ * Return null if this is not possible.
+ */
+ static MethodHandle makeSwapArguments(MethodType newType, MethodHandle target,
+ int swapArg1, int swapArg2) {
+ if (swapArg1 == swapArg2)
+ return target;
+ if (swapArg1 > swapArg2) { int t = swapArg1; swapArg1 = swapArg2; swapArg2 = t; }
+ if (!canSwapArguments(newType, target.type(), swapArg1, swapArg2))
+ return null;
+ Class> swapType = newType.parameterType(swapArg1);
+ // in arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
+ // out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
+ int swapSlot2 = newType.parameterSlotDepth(swapArg2 + 1);
+ long conv = makeSwapConv(OP_SWAP_ARGS, swapArg1, basicType(swapType), swapSlot2);
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+
+ static int positiveRotation(int argCount, int rotateBy) {
+ assert(argCount > 0);
+ if (rotateBy >= 0) {
+ if (rotateBy < argCount)
+ return rotateBy;
+ return rotateBy % argCount;
+ } else if (rotateBy >= -argCount) {
+ return rotateBy + argCount;
+ } else {
+ return (-1-((-1-rotateBy) % argCount)) + argCount;
+ }
+ }
+
+ final static int MAX_ARG_ROTATION = 1;
+
+ /** Can an adapter rotate arguments to convert the target to newType? */
+ static boolean canRotateArguments(MethodType newType, MethodType targetType,
+ int firstArg, int argCount, int rotateBy) {
+ if (!convOpSupported(OP_ROT_ARGS)) return false;
+ if (argCount <= 2) return false; // must be a swap, not a rotate
+ rotateBy = positiveRotation(argCount, rotateBy);
+ if (rotateBy == 0) return false; // no rotation
+ if (rotateBy > MAX_ARG_ROTATION && rotateBy < argCount - MAX_ARG_ROTATION)
+ return false; // too many argument positions
+ // Rotate incoming args right N to the out args, N in 1..(argCouunt-1).
+ if (diffReturnTypes(newType, targetType, false) != 0)
+ return false;
+ int nptypes = newType.parameterCount();
+ if (targetType.parameterCount() != nptypes)
+ return false;
+ if (firstArg < 0 || firstArg >= nptypes) return false;
+ int argLimit = firstArg + argCount;
+ if (argLimit > nptypes) return false;
+ if (diffParamTypes(newType, 0, targetType, 0, firstArg, false) != 0)
+ return false;
+ int newChunk1 = argCount - rotateBy, newChunk2 = rotateBy;
+ // swap new chunk1 with target chunk2
+ if (diffParamTypes(newType, firstArg, targetType, argLimit-newChunk1, newChunk1, false) != 0)
+ return false;
+ // swap new chunk2 with target chunk1
+ if (diffParamTypes(newType, firstArg+newChunk1, targetType, firstArg, newChunk2, false) != 0)
+ return false;
+ return true;
+ }
+
+ /** Factory method: Rotate the selected argument range.
+ * Return null if this is not possible.
+ */
+ static MethodHandle makeRotateArguments(MethodType newType, MethodHandle target,
+ int firstArg, int argCount, int rotateBy) {
+ rotateBy = positiveRotation(argCount, rotateBy);
+ if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy))
+ return null;
+ // Decide whether it should be done as a right or left rotation,
+ // on the JVM stack. Return the number of stack slots to rotate by,
+ // positive if right, negative if left.
+ int limit = firstArg + argCount;
+ int depth0 = newType.parameterSlotDepth(firstArg);
+ int depth1 = newType.parameterSlotDepth(limit-rotateBy);
+ int depth2 = newType.parameterSlotDepth(limit);
+ int chunk1Slots = depth0 - depth1; assert(chunk1Slots > 0);
+ int chunk2Slots = depth1 - depth2; assert(chunk2Slots > 0);
+ // From here on out, it assumes a single-argument shift.
+ assert(MAX_ARG_ROTATION == 1);
+ int srcArg, dstArg;
+ byte basicType;
+ if (chunk2Slots <= chunk1Slots) {
+ // Rotate right/down N (rotateBy = +N, N small, c2 small):
+ // in arglist: [0: ...keep1 | arg1: c1... | limit-N: c2 | limit: keep2... ]
+ // out arglist: [0: ...keep1 | arg1: c2 | arg1+N: c1... | limit: keep2... ]
+ srcArg = limit-1;
+ dstArg = firstArg;
+ basicType = basicType(newType.parameterType(srcArg));
+ assert(chunk2Slots == type2size(basicType));
+ } else {
+ // Rotate left/up N (rotateBy = -N, N small, c1 small):
+ // in arglist: [0: ...keep1 | arg1: c1 | arg1+N: c2... | limit: keep2... ]
+ // out arglist: [0: ...keep1 | arg1: c2 ... | limit-N: c1 | limit: keep2... ]
+ srcArg = firstArg;
+ dstArg = limit-1;
+ basicType = basicType(newType.parameterType(srcArg));
+ assert(chunk1Slots == type2size(basicType));
+ }
+ int dstSlot = newType.parameterSlotDepth(dstArg + 1);
+ long conv = makeSwapConv(OP_ROT_ARGS, srcArg, basicType, dstSlot);
+ return new AdapterMethodHandle(target, newType, conv);
+ }
+
+ /** Can an adapter spread an argument to convert the target to newType? */
+ static boolean canSpreadArguments(MethodType newType, MethodType targetType,
+ Class> spreadArgType, int spreadArgPos, int spreadArgCount) {
+ if (!convOpSupported(OP_SPREAD_ARGS)) return false;
+ if (diffReturnTypes(newType, targetType, false) != 0)
+ return false;
+ int nptypes = newType.parameterCount();
+ // parameter types must be the same up to the spread point
+ if (spreadArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, spreadArgPos, false) != 0)
+ return false;
+ int afterPos = spreadArgPos + spreadArgCount;
+ int afterCount = nptypes - (spreadArgPos + 1);
+ if (spreadArgPos < 0 || spreadArgPos >= nptypes ||
+ spreadArgCount < 0 ||
+ targetType.parameterCount() != afterPos + afterCount)
+ return false;
+ // parameter types after the spread point must also be the same
+ if (afterCount != 0 && diffParamTypes(newType, spreadArgPos+1, targetType, afterPos, afterCount, false) != 0)
+ return false;
+ // match the array element type to the spread arg types
+ Class> rawSpreadArgType = newType.parameterType(spreadArgPos);
+ if (rawSpreadArgType != spreadArgType && !canCheckCast(rawSpreadArgType, spreadArgType))
+ return false;
+ for (int i = 0; i < spreadArgCount; i++) {
+ Class> src = VerifyType.spreadArgElementType(spreadArgType, i);
+ Class> dst = targetType.parameterType(spreadArgPos + i);
+ if (src == null || !VerifyType.isNullConversion(src, dst))
+ return false;
+ }
+ return true;
+ }
+
+
+ /** Factory method: Spread selected argument. */
+ static MethodHandle makeSpreadArguments(MethodType newType, MethodHandle target,
+ Class> spreadArgType, int spreadArgPos, int spreadArgCount) {
+ MethodType targetType = target.type();
+ if (!canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount))
+ return null;
+ // in arglist: [0: ...keep1 | spos: spreadArg | spos+1: keep2... ]
+ // out arglist: [0: ...keep1 | spos: spread... | spos+scount: keep2... ]
+ int keep2OutPos = spreadArgPos + spreadArgCount;
+ int spreadSlot = targetType.parameterSlotDepth(keep2OutPos);
+ int keep1OutSlot = targetType.parameterSlotDepth(spreadArgPos);
+ int slotCount = keep1OutSlot - spreadSlot;
+ assert(spreadSlot == newType.parameterSlotDepth(spreadArgPos+1));
+ assert(slotCount >= spreadArgCount);
+ long conv = makeConv(OP_SPREAD_ARGS, spreadArgPos, slotCount-1);
+ MethodHandle res = new AdapterMethodHandle(target, newType, conv, spreadArgType);
+ assert(res.type().parameterType(spreadArgPos) == spreadArgType);
+ return res;
+ }
+
+ // TO DO: makeCollectArguments, makeFlyby, makeRicochet
+
+ @Override
+ public String toString() {
+ return getNameString(nonAdapter((MethodHandle)vmtarget), this);
+ }
+
+ private static MethodHandle nonAdapter(MethodHandle mh) {
+ while (mh instanceof AdapterMethodHandle) {
+ mh = (MethodHandle) mh.vmtarget;
+ }
+ return mh;
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.VerifyType;
+import sun.invoke.util.Wrapper;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * The flavor of method handle which emulates an invoke instruction
+ * on a predetermined argument. The JVM dispatches to the correct method
+ * when the handle is created, not when it is invoked.
+ * @author jrose
+ */
+class BoundMethodHandle extends MethodHandle {
+ //MethodHandle vmtarget; // next BMH or final DMH or methodOop
+ private final Object argument; // argument to insert
+ private final int vmargslot; // position at which it is inserted
+
+ // Constructors in this class *must* be package scoped or private.
+
+ /** Bind a direct MH to its receiver (or first ref. argument).
+ * The JVM will pre-dispatch the MH if it is not already static.
+ */
+ /*non-public*/ BoundMethodHandle(DirectMethodHandle mh, Object argument) {
+ super(mh.type().dropParameterTypes(0, 1));
+ // check the type now, once for all:
+ this.argument = checkReferenceArgument(argument, mh, 0);
+ this.vmargslot = this.type().parameterSlotCount();
+ initTarget(mh, 0);
+ }
+
+ /** Insert an argument into an arbitrary method handle.
+ * If argnum is zero, inserts the first argument, etc.
+ * The argument type must be a reference.
+ */
+ /*non-public*/ BoundMethodHandle(MethodHandle mh, Object argument, int argnum) {
+ this(mh.type().dropParameterTypes(argnum, argnum+1),
+ mh, argument, argnum);
+ }
+
+ /** Insert an argument into an arbitrary method handle.
+ * If argnum is zero, inserts the first argument, etc.
+ */
+ /*non-public*/ BoundMethodHandle(MethodType type, MethodHandle mh, Object argument, int argnum) {
+ super(type);
+ if (mh.type().parameterType(argnum).isPrimitive())
+ this.argument = bindPrimitiveArgument(argument, mh, argnum);
+ else {
+ this.argument = checkReferenceArgument(argument, mh, argnum);
+ }
+ this.vmargslot = type.parameterSlotDepth(argnum);
+ initTarget(mh, argnum);
+ }
+
+ private void initTarget(MethodHandle mh, int argnum) {
+ //this.vmtarget = mh; // maybe updated by JVM
+ MethodHandleNatives.init(this, mh, argnum);
+ }
+
+ /** For the AdapterMethodHandle subclass.
+ */
+ /*non-public*/ BoundMethodHandle(MethodType type, Object argument, int vmargslot) {
+ super(type);
+ this.argument = argument;
+ this.vmargslot = vmargslot;
+ assert(this instanceof AdapterMethodHandle);
+ }
+
+ /** Initialize the current object as a self-bound method handle, binding it
+ * as the first argument of the method handle {@code entryPoint}.
+ * The invocation type of the resulting method handle will be the
+ * same as {@code entryPoint}, except that the first argument
+ * type will be dropped.
+ */
+ /*non-public*/ BoundMethodHandle(MethodHandle entryPoint) {
+ super(entryPoint.type().dropParameterTypes(0, 1));
+ this.argument = this; // kludge; get rid of
+ this.vmargslot = this.type().parameterSlotDepth(0);
+ initTarget(entryPoint, 0);
+ }
+
+ /** Make sure the given {@code argument} can be used as {@code argnum}-th
+ * parameter of the given method handle {@code mh}, which must be a reference.
+ *
+ * If this fails, throw a suitable {@code WrongMethodTypeException},
+ * which will prevent the creation of an illegally typed bound
+ * method handle.
+ */
+ final static Object checkReferenceArgument(Object argument, MethodHandle mh, int argnum) {
+ Class> ptype = mh.type().parameterType(argnum);
+ if (ptype.isPrimitive()) {
+ // fail
+ } else if (argument == null) {
+ return null;
+ } else if (VerifyType.isNullReferenceConversion(argument.getClass(), ptype)) {
+ return argument;
+ }
+ throw badBoundArgumentException(argument, mh, argnum);
+ }
+
+ /** Make sure the given {@code argument} can be used as {@code argnum}-th
+ * parameter of the given method handle {@code mh}, which must be a primitive.
+ *
+ * If this fails, throw a suitable {@code WrongMethodTypeException},
+ * which will prevent the creation of an illegally typed bound
+ * method handle.
+ */
+ final static Object bindPrimitiveArgument(Object argument, MethodHandle mh, int argnum) {
+ Class> ptype = mh.type().parameterType(argnum);
+ Wrapper wrap = Wrapper.forPrimitiveType(ptype);
+ Object zero = wrap.zero();
+ if (zero == null) {
+ // fail
+ } else if (argument == null) {
+ if (ptype != int.class && wrap.isSubwordOrInt())
+ return Integer.valueOf(0);
+ else
+ return zero;
+ } else if (VerifyType.isNullReferenceConversion(argument.getClass(), zero.getClass())) {
+ if (ptype != int.class && wrap.isSubwordOrInt())
+ return Wrapper.INT.wrap(argument);
+ else
+ return argument;
+ }
+ throw badBoundArgumentException(argument, mh, argnum);
+ }
+
+ final static RuntimeException badBoundArgumentException(Object argument, MethodHandle mh, int argnum) {
+ String atype = (argument == null) ? "null" : argument.getClass().toString();
+ return new WrongMethodTypeException("cannot bind "+atype+" argument to parameter #"+argnum+" of "+mh.type());
+ }
+
+ @Override
+ public String toString() {
+ return addTypeString(baseName(), this);
+ }
+
+ /** Component of toString() before the type string. */
+ protected String baseName() {
+ MethodHandle mh = this;
+ while (mh instanceof BoundMethodHandle) {
+ Object info = MethodHandleNatives.getTargetInfo(mh);
+ if (info instanceof MethodHandle) {
+ mh = (MethodHandle) info;
+ } else {
+ String name = null;
+ if (info instanceof MemberName)
+ name = ((MemberName)info).getName();
+ if (name != null)
+ return name;
+ else
+ return noParens(super.toString()); // "invoke", probably
+ }
+ assert(mh != this);
+ }
+ return noParens(mh.toString());
+ }
+
+ private static String noParens(String str) {
+ int paren = str.indexOf('(');
+ if (paren >= 0) str = str.substring(0, paren);
+ return str;
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/CallSite.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.empty.Empty;
+import sun.misc.Unsafe;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * A {@code CallSite} is a holder for a variable {@link MethodHandle},
+ * which is called its {@code target}.
+ * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
+ * all calls to the site's current target.
+ * A {@code CallSite} may be associated with several {@code invokedynamic}
+ * instructions, or it may be "free floating", associated with none.
+ * In any case, it may be invoked through an associated method handle
+ * called its {@linkplain #dynamicInvoker dynamic invoker}.
+ *
+ * {@code CallSite} is an abstract class which does not allow
+ * direct subclassing by users. It has three immediate,
+ * concrete subclasses that may be either instantiated or subclassed.
+ *
+ * If a mutable target is not required, an {@code invokedynamic} instruction
+ * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
+ * If a mutable target is required which has volatile variable semantics,
+ * because updates to the target must be immediately and reliably witnessed by other threads,
+ * a {@linkplain VolatileCallSite volatile call site} may be used.
+ * Otherwise, if a mutable target is required,
+ * a {@linkplain MutableCallSite mutable call site} may be used.
+ *
+ *
+ * A non-constant call site may be relinked by changing its target.
+ * The new target must have the same {@linkplain MethodHandle#type() type}
+ * as the previous target.
+ * Thus, though a call site can be relinked to a series of
+ * successive targets, it cannot change its type.
+ *
+ * Here is a sample use of call sites and bootstrap methods which links every
+ * dynamic call site to print its arguments:
+
+static void test() throws Throwable {
+ // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
+ InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
+}
+private static void printArgs(Object... args) {
+ System.out.println(java.util.Arrays.deepToString(args));
+}
+private static final MethodHandle printArgs;
+static {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ Class thisClass = lookup.lookupClass(); // (who am I?)
+ printArgs = lookup.findStatic(thisClass,
+ "printArgs", MethodType.methodType(void.class, Object[].class));
+}
+private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
+ // ignore caller and name, but match the type:
+ return new ConstantCallSite(printArgs.asType(type));
+}
+
+ * @author John Rose, JSR 292 EG
+ */
+abstract
+public class CallSite {
+ static { MethodHandleImpl.initStatics(); }
+
+ // Fields used only by the JVM. Do not use or change.
+ private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
+ private int vmindex; // supplied by the JVM (BCI within calling method)
+
+ // The actual payload of this call site:
+ /*package-private*/
+ MethodHandle target;
+
+ /**
+ * Make a blank call site object with the given method type.
+ * An initial target method is supplied which will throw
+ * an {@link IllegalStateException} if called.
+ *
+ * Before this {@code CallSite} object is returned from a bootstrap method,
+ * it is usually provided with a more useful target method,
+ * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
+ * @throws NullPointerException if the proposed type is null
+ */
+ /*package-private*/
+ CallSite(MethodType type) {
+ target = type.invokers().uninitializedCallSite();
+ }
+
+ /**
+ * Make a blank call site object, possibly equipped with an initial target method handle.
+ * @param target the method handle which will be the initial target of the call site
+ * @throws NullPointerException if the proposed target is null
+ */
+ /*package-private*/
+ CallSite(MethodHandle target) {
+ target.type(); // null check
+ this.target = target;
+ }
+
+ /**
+ * Returns the type of this call site's target.
+ * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
+ * The {@code setTarget} method enforces this invariant by refusing any new target that does
+ * not have the previous target's type.
+ * @return the type of the current target, which is also the type of any future target
+ */
+ public MethodType type() {
+ return target.type();
+ }
+
+ /** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
+ * The parameters are JVM-specific.
+ */
+ void initializeFromJVM(String name,
+ MethodType type,
+ MemberName callerMethod,
+ int callerBCI) {
+ if (this.vmmethod != null) {
+ // FIXME
+ throw new BootstrapMethodError("call site has already been linked to an invokedynamic instruction");
+ }
+ if (!this.type().equals(type)) {
+ throw wrongTargetType(target, type);
+ }
+ this.vmindex = callerBCI;
+ this.vmmethod = callerMethod;
+ }
+
+ /**
+ * Returns the target method of the call site, according to the
+ * behavior defined by this call site's specific class.
+ * The immediate subclasses of {@code CallSite} document the
+ * class-specific behaviors of this method.
+ *
+ * @return the current linkage state of the call site, its target method handle
+ * @see ConstantCallSite
+ * @see VolatileCallSite
+ * @see #setTarget
+ * @see ConstantCallSite#getTarget
+ * @see MutableCallSite#getTarget
+ * @see VolatileCallSite#getTarget
+ */
+ public abstract MethodHandle getTarget();
+
+ /**
+ * Updates the target method of this call site, according to the
+ * behavior defined by this call site's specific class.
+ * The immediate subclasses of {@code CallSite} document the
+ * class-specific behaviors of this method.
+ *
+ * The type of the new target must be {@linkplain MethodType#equals equal to}
+ * the type of the old target.
+ *
+ * @param newTarget the new target
+ * @throws NullPointerException if the proposed new target is null
+ * @throws WrongMethodTypeException if the proposed new target
+ * has a method type that differs from the previous target
+ * @see CallSite#getTarget
+ * @see ConstantCallSite#setTarget
+ * @see MutableCallSite#setTarget
+ * @see VolatileCallSite#setTarget
+ */
+ public abstract void setTarget(MethodHandle newTarget);
+
+ void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
+ MethodType oldType = oldTarget.type();
+ MethodType newType = newTarget.type(); // null check!
+ if (!newType.equals(oldType))
+ throw wrongTargetType(newTarget, oldType);
+ }
+
+ private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
+ return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
+ }
+
+ /**
+ * Produces a method handle equivalent to an invokedynamic instruction
+ * which has been linked to this call site.
+ *
+ * This method is equivalent to the following code:
+ *
+ * MethodHandle getTarget, invoker, result;
+ * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
+ * invoker = MethodHandles.exactInvoker(this.type());
+ * result = MethodHandles.foldArguments(invoker, getTarget)
+ *
+ *
+ * @return a method handle which always invokes this call site's current target
+ */
+ public abstract MethodHandle dynamicInvoker();
+
+ /*non-public*/ MethodHandle makeDynamicInvoker() {
+ MethodHandle getTarget = MethodHandleImpl.bindReceiver(GET_TARGET, this);
+ MethodHandle invoker = MethodHandles.exactInvoker(this.type());
+ return MethodHandles.foldArguments(invoker, getTarget);
+ }
+
+ private static final MethodHandle GET_TARGET;
+ static {
+ try {
+ GET_TARGET = IMPL_LOOKUP.
+ findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
+ } catch (ReflectiveOperationException ignore) {
+ throw new InternalError();
+ }
+ }
+
+ /** This guy is rolled into the default target if a MethodType is supplied to the constructor. */
+ /*package-private*/
+ static Empty uninitializedCallSite() {
+ throw new IllegalStateException("uninitialized call site");
+ }
+
+ // unsafe stuff:
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final long TARGET_OFFSET;
+
+ static {
+ try {
+ TARGET_OFFSET = unsafe.objectFieldOffset(CallSite.class.getDeclaredField("target"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ /*package-private*/
+ void setTargetNormal(MethodHandle newTarget) {
+ target = newTarget;
+ }
+ /*package-private*/
+ MethodHandle getTargetVolatile() {
+ return (MethodHandle) unsafe.getObjectVolatile(this, TARGET_OFFSET);
+ }
+ /*package-private*/
+ void setTargetVolatile(MethodHandle newTarget) {
+ unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget);
+ }
+
+ // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
+ static CallSite makeSite(MethodHandle bootstrapMethod,
+ // Callee information:
+ String name, MethodType type,
+ // Extra arguments for BSM, if any:
+ Object info,
+ // Caller information:
+ MemberName callerMethod, int callerBCI) {
+ Class> callerClass = callerMethod.getDeclaringClass();
+ Object caller = IMPL_LOOKUP.in(callerClass);
+ CallSite site;
+ try {
+ Object binding;
+ info = maybeReBox(info);
+ if (info == null) {
+ binding = bootstrapMethod.invokeGeneric(caller, name, type);
+ } else if (!info.getClass().isArray()) {
+ binding = bootstrapMethod.invokeGeneric(caller, name, type, info);
+ } else {
+ Object[] argv = (Object[]) info;
+ maybeReBoxElements(argv);
+ if (3 + argv.length > 255)
+ throw new BootstrapMethodError("too many bootstrap method arguments");
+ MethodType bsmType = bootstrapMethod.type();
+ if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
+ binding = bootstrapMethod.invokeGeneric(caller, name, type, argv);
+ else
+ binding = MethodHandles.spreadInvoker(bsmType, 3)
+ .invokeGeneric(bootstrapMethod, caller, name, type, argv);
+ }
+ //System.out.println("BSM for "+name+type+" => "+binding);
+ if (binding instanceof CallSite) {
+ site = (CallSite) binding;
+ } else {
+ throw new ClassCastException("bootstrap method failed to produce a CallSite");
+ }
+ assert(site.getTarget() != null);
+ assert(site.getTarget().type().equals(type));
+ } catch (Throwable ex) {
+ BootstrapMethodError bex;
+ if (ex instanceof BootstrapMethodError)
+ bex = (BootstrapMethodError) ex;
+ else
+ bex = new BootstrapMethodError("call site initialization exception", ex);
+ throw bex;
+ }
+ return site;
+ }
+
+ private static Object maybeReBox(Object x) {
+ if (x instanceof Integer) {
+ int xi = (int) x;
+ if (xi == (byte) xi)
+ x = xi; // must rebox; see JLS 5.1.7
+ }
+ return x;
+ }
+ private static void maybeReBoxElements(Object[] xa) {
+ for (int i = 0; i < xa.length; i++) {
+ xa[i] = maybeReBox(xa[i]);
+ }
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/ConstantCallSite.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/ConstantCallSite.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+/**
+ * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
+ * An {@code invokedynamic} instruction linked to a {@code ConstantCallSite} is permanently
+ * bound to the call site's target.
+ * @author John Rose, JSR 292 EG
+ */
+public class ConstantCallSite extends CallSite {
+ /**
+ * Creates a call site with a permanent target.
+ * @param target the target to be permanently associated with this call site
+ * @throws NullPointerException if the proposed target is null
+ */
+ public ConstantCallSite(MethodHandle target) {
+ super(target);
+ }
+
+ /**
+ * Returns the target method of the call site, which behaves
+ * like a {@code final} field of the {@code ConstantCallSite}.
+ * That is, the the target is always the original value passed
+ * to the constructor call which created this instance.
+ *
+ * @return the immutable linkage state of this call site, a constant method handle
+ * @throws UnsupportedOperationException because this kind of call site cannot change its target
+ */
+ @Override public final MethodHandle getTarget() {
+ return target;
+ }
+
+ /**
+ * Always throws an {@link UnsupportedOperationException}.
+ * This kind of call site cannot change its target.
+ * @param ignore a new target proposed for the call site, which is ignored
+ * @throws UnsupportedOperationException because this kind of call site cannot change its target
+ */
+ @Override public final void setTarget(MethodHandle ignore) {
+ throw new UnsupportedOperationException("ConstantCallSite");
+ }
+
+ /**
+ * Returns this call site's permanent target.
+ * Since that target will never change, this is a correct implementation
+ * of {@link CallSite#dynamicInvoker CallSite.dynamicInvoker}.
+ * @return the immutable linkage state of this call site, a constant method handle
+ */
+ @Override
+ public final MethodHandle dynamicInvoker() {
+ return getTarget();
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+
+/**
+ * The flavor of method handle which emulates invokespecial or invokestatic.
+ * @author jrose
+ */
+class DirectMethodHandle extends MethodHandle {
+ //inherited oop vmtarget; // methodOop or virtual class/interface oop
+ private final int vmindex; // method index within class or interface
+ { vmindex = VM_INDEX_UNINITIALIZED; } // JVM may change this
+
+ // Constructors in this class *must* be package scoped or private.
+ DirectMethodHandle(MethodType mtype, MemberName m, boolean doDispatch, Class> lookupClass) {
+ super(mtype);
+
+ assert(m.isMethod() || !doDispatch && m.isConstructor());
+ if (!m.isResolved())
+ throw new InternalError();
+
+ MethodHandleNatives.init(this, (Object) m, doDispatch, lookupClass);
+ }
+
+ boolean isValid() {
+ return (vmindex != VM_INDEX_UNINITIALIZED);
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/FilterGeneric.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/FilterGeneric.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,4496 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.*;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * These adapters apply arbitrary conversions to arguments
+ * on the way to a ultimate target.
+ * For simplicity, these are all generically typed.
+ * @author jrose
+ */
+class FilterGeneric {
+ // type for the incoming call (will be generic)
+ private final MethodType entryType;
+ // prototype adapters (clone and customize for each new target & conversion!)
+ private final Adapter[] adapters;
+
+ /** Compute and cache information common to all filtering adapters
+ * with the given generic type
+ */
+ FilterGeneric(MethodType entryType) {
+ this.entryType = entryType;
+ int tableSize = Kind.LIMIT.invokerIndex(1 + entryType.parameterCount());
+ this.adapters = new Adapter[tableSize];
+ }
+
+ Adapter getAdapter(Kind kind, int pos) {
+ int index = kind.invokerIndex(pos);
+ Adapter ad = adapters[index];
+ if (ad != null) return ad;
+ ad = findAdapter(entryType, kind, pos);
+ if (ad == null)
+ ad = buildAdapterFromBytecodes(entryType, kind, pos);
+ adapters[index] = ad;
+ return ad;
+ }
+
+ Adapter makeInstance(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
+ Adapter ad = getAdapter(kind, pos);
+ return ad.makeInstance(ad.prototypeEntryPoint(), filter, target);
+ }
+
+ /** Build an adapter of the given generic type, which invokes filter
+ * on the selected incoming argument before passing it to the target.
+ * @param pos the argument to filter
+ * @param filter the function to call on the argument
+ * @param target the target to call with the modified argument list
+ * @return an adapter method handle
+ */
+ public static MethodHandle makeArgumentFilter(int pos, MethodHandle filter, MethodHandle target) {
+ return make(Kind.value, pos, filter, target);
+ }
+
+ /** Build an adapter of the given generic type, which invokes a combiner
+ * on a selected group of leading arguments.
+ * The result of the combiner is prepended before all those arguments.
+ * @param combiner the function to call on the selected leading arguments
+ * @param target the target to call with the modified argument list
+ * @return an adapter method handle
+ */
+ public static MethodHandle makeArgumentFolder(MethodHandle combiner, MethodHandle target) {
+ int num = combiner.type().parameterCount();
+ return make(Kind.fold, num, combiner, target);
+ }
+
+ /** Build an adapter of the given generic type, which invokes a filter
+ * on the incoming arguments, reified as a group.
+ * The argument may be modified (by side effects in the filter).
+ * The arguments, possibly modified, are passed on to the target.
+ * @param filter the function to call on the arguments
+ * @param target the target to call with the possibly-modified argument list
+ * @return an adapter method handle
+ */
+ public static MethodHandle makeFlyby(MethodHandle filter, MethodHandle target) {
+ return make(Kind.flyby, 0, filter, target);
+ }
+
+ /** Build an adapter of the given generic type, which invokes a collector
+ * on the selected incoming argument and all following arguments.
+ * The result of the collector replaces all those arguments.
+ * @param collector the function to call on the selected trailing arguments
+ * @param target the target to call with the modified argument list
+ * @return an adapter method handle
+ */
+ public static MethodHandle makeArgumentCollector(MethodHandle collector, MethodHandle target) {
+ int pos = target.type().parameterCount() - 1;
+ return make(Kind.collect, pos, collector, target);
+ }
+
+ static MethodHandle make(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
+ FilterGeneric fgen = of(kind, pos, filter.type(), target.type());
+ return fgen.makeInstance(kind, pos, filter, target);
+ }
+
+ /** Return the adapter information for this target and filter type. */
+ static FilterGeneric of(Kind kind, int pos, MethodType filterType, MethodType targetType) {
+ MethodType entryType = entryType(kind, pos, filterType, targetType);
+ if (entryType.generic() != entryType)
+ throw newIllegalArgumentException("must be generic: "+entryType);
+ MethodTypeForm form = entryType.form();
+ FilterGeneric filterGen = form.filterGeneric;
+ if (filterGen == null)
+ form.filterGeneric = filterGen = new FilterGeneric(entryType);
+ return filterGen;
+ }
+
+ public String toString() {
+ return "FilterGeneric/"+entryType;
+ }
+
+ static MethodType targetType(MethodType entryType, Kind kind, int pos, MethodType filterType) {
+ MethodType type = entryType;
+ switch (kind) {
+ case value:
+ case flyby:
+ break; // no change
+ case fold:
+ type = type.insertParameterTypes(0, filterType.returnType());
+ break;
+ case collect:
+ type = type.dropParameterTypes(pos, type.parameterCount());
+ type = type.insertParameterTypes(pos, filterType.returnType());
+ break;
+ default:
+ throw new InternalError();
+ }
+ return type;
+ }
+
+ static MethodType entryType(Kind kind, int pos, MethodType filterType, MethodType targetType) {
+ MethodType type = targetType;
+ switch (kind) {
+ case value:
+ case flyby:
+ break; // no change
+ case fold:
+ type = type.dropParameterTypes(0, 1);
+ break;
+ case collect:
+ type = type.dropParameterTypes(pos, pos+1);
+ type = type.insertParameterTypes(pos, filterType.parameterList());
+ break;
+ default:
+ throw new InternalError();
+ }
+ return type;
+ }
+
+ /* Create an adapter that handles spreading calls for the given type. */
+ static Adapter findAdapter(MethodType entryType, Kind kind, int pos) {
+ int argc = entryType.parameterCount();
+ String cname0 = "F"+argc;
+ String cname1 = "F"+argc+kind.key;
+ String[] cnames = { cname0, cname1 };
+ String iname = kind.invokerName(pos);
+ // e.g., F5; invoke_C3
+ for (String cname : cnames) {
+ Class extends Adapter> acls = Adapter.findSubClass(cname);
+ if (acls == null) continue;
+ // see if it has the required invoke method
+ MethodHandle entryPoint = null;
+ try {
+ entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
+ } catch (ReflectiveOperationException ex) {
+ }
+ if (entryPoint == null) continue;
+ Constructor extends Adapter> ctor = null;
+ try {
+ ctor = acls.getDeclaredConstructor(MethodHandle.class);
+ } catch (NoSuchMethodException ex) {
+ } catch (SecurityException ex) {
+ }
+ if (ctor == null) continue;
+ try {
+ // Produce an instance configured as a prototype.
+ return ctor.newInstance(entryPoint);
+ } catch (IllegalArgumentException ex) {
+ } catch (InvocationTargetException wex) {
+ Throwable ex = wex.getTargetException();
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ } catch (InstantiationException ex) {
+ } catch (IllegalAccessException ex) {
+ }
+ }
+ return null;
+ }
+
+ static Adapter buildAdapterFromBytecodes(MethodType entryType, Kind kind, int pos) {
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ /**
+ * This adapter takes some untyped arguments, and returns an untyped result.
+ * Internally, it applies the invoker to the target, which causes the
+ * objects to be unboxed; the result is a raw type in L/I/J/F/D.
+ * This result is passed to convert, which is responsible for
+ * converting the raw result into a boxed object.
+ * The invoker is kept separate from the target because it can be
+ * generated once per type erasure family, and reused across adapters.
+ */
+ static abstract class Adapter extends BoundMethodHandle {
+ protected final MethodHandle filter; // transforms one or more arguments
+ protected final MethodHandle target; // ultimate target
+
+ @Override
+ public String toString() {
+ return addTypeString(target, this);
+ }
+
+ protected boolean isPrototype() { return target == null; }
+ protected Adapter(MethodHandle entryPoint) {
+ this(entryPoint, entryPoint, null);
+ assert(isPrototype());
+ }
+ protected MethodHandle prototypeEntryPoint() {
+ if (!isPrototype()) throw new InternalError();
+ return filter;
+ }
+
+ protected Adapter(MethodHandle entryPoint,
+ MethodHandle filter, MethodHandle target) {
+ super(entryPoint);
+ this.filter = filter;
+ this.target = target;
+ }
+
+ /** Make a copy of self, with new fields. */
+ protected abstract Adapter makeInstance(MethodHandle entryPoint,
+ MethodHandle filter, MethodHandle target);
+ // { return new ThisType(entryPoint, filter, target); }
+
+ static private final String CLASS_PREFIX; // "java.lang.invoke.FilterGeneric$"
+ static {
+ String aname = Adapter.class.getName();
+ String sname = Adapter.class.getSimpleName();
+ if (!aname.endsWith(sname)) throw new InternalError();
+ CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
+ }
+ /** Find a sibing class of Adapter. */
+ static Class extends Adapter> findSubClass(String name) {
+ String cname = Adapter.CLASS_PREFIX + name;
+ try {
+ return Class.forName(cname).asSubclass(Adapter.class);
+ } catch (ClassNotFoundException ex) {
+ return null;
+ } catch (ClassCastException ex) {
+ return null;
+ }
+ }
+ }
+
+ static enum Kind {
+ value('V'), // filter and replace Nth argument value
+ fold('F'), // fold first N arguments, prepend result
+ collect('C'), // collect last N arguments, replace with result
+ flyby('Y'), // reify entire argument list, filter, pass to target
+ LIMIT('?');
+ static final int COUNT = LIMIT.ordinal();
+
+ final char key;
+ Kind(char key) { this.key = key; }
+ String invokerName(int pos) { return "invoke_"+key+""+pos; }
+ int invokerIndex(int pos) { return pos * COUNT + ordinal(); }
+ }
+
+ /* generated classes follow this pattern:
+ static class F1X extends Adapter {
+ protected F1X(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F1X(MethodHandle e, MethodHandle f, MethodHandle t)
+ { super(e, f, t); }
+ protected F1X makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
+ { return new F1X(e, f, t); }
+ protected Object invoke_V0(Object a0) { return target.invokeExact(filter.invokeExact(a0)); }
+ protected Object invoke_F0(Object a0) { return target.invokeExact(filter.invokeExact(), a0); }
+ protected Object invoke_F1(Object a0) { return target.invokeExact(filter.invokeExact(a0), a0); }
+ protected Object invoke_C0(Object a0) { return target.invokeExact(filter.invokeExact(a0)); }
+ protected Object invoke_C1(Object a0) { return target.invokeExact(a0, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0) { Object[] av = { a0 };
+ filter.invokeExact(av); return target.invokeExact(av[0]); }
+ }
+ static class F2X extends Adapter {
+ protected F2X(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F2X(MethodHandle e, MethodHandle f, MethodHandle t)
+ { super(e, f, t); }
+ protected F2X makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
+ { return new F2X(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0), a1); }
+ protected Object invoke_V1(Object a0, Object a1) { return target.invokeExact(a0, filter.invokeExact(a1)); }
+ protected Object invoke_F0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(), a0, a1); }
+ protected Object invoke_F1(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0), a0, a1); }
+ protected Object invoke_F2(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0, a1), a0, a1); }
+ protected Object invoke_C0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0, a1)); }
+ protected Object invoke_C1(Object a0, Object a1) { return target.invokeExact(a0, filter.invokeExact(a1)); }
+ protected Object invoke_C2(Object a0, Object a1) { return target.invokeExact(a0, a1, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1) { Object[] av = { a0, a1 };
+ filter.invokeExact(av); return target.invokeExact(av[0], av[1]); }
+ }
+ // */
+
+ // This one is written by hand:
+ static class F0 extends Adapter {
+ protected F0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F0(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F0 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F0(e, f, t); }
+ protected Object invoke_F0() throws Throwable {
+ return target.invokeExact(filter.invokeExact()); }
+ protected Object invoke_C0() throws Throwable {
+ return target.invokeExact(filter.invokeExact()); }
+ static final Object[] NO_ARGS = { };
+ protected Object invoke_Y0() throws Throwable {
+ filter.invokeExact(NO_ARGS); // make the flyby
+ return target.invokeExact(); }
+ }
+
+/*
+ : SHELL; n=FilterGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -ea -cp . genclasses | sed 's| *[/]/ *$||') >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
+//{{{
+import java.util.*;
+class genclasses {
+ static String[][] TEMPLATES = { {
+ "@for@ N=1..20",
+ " //@each-cat@",
+ " static class @cat@ extends Adapter {",
+ " protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
+ " protected @cat@(MethodHandle e, MethodHandle f, MethodHandle t) {",
+ " super(e, f, t); }",
+ " protected @cat@ makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {",
+ " return new @cat@(e, f, t); }",
+ " //@each-P@",
+ " protected Object invoke_V@P@(@Tvav@) throws Throwable {",
+ " return target.invokeExact(@a0_@@Psp@filter.invokeExact(a@P@)@_aN@); }",
+ " //@end-P@",
+ " //@each-P@",
+ " protected Object invoke_F@P@(@Tvav@) throws Throwable {",
+ " return target.invokeExact(filter.invokeExact(@a0@),",
+ " @av@); }",
+ " //@end-P@",
+ " protected Object invoke_F@N@(@Tvav@) throws Throwable {",
+ " return target.invokeExact(filter.invokeExact(@av@),",
+ " @av@); }",
+ " //@each-P@",
+ " protected Object invoke_C@P@(@Tvav@) throws Throwable {",
+ " return target.invokeExact(@a0_@filter.invokeExact(a@P@@_aN@)); }",
+ " //@end-P@",
+ " protected Object invoke_C@N@(@Tvav@) throws Throwable {",
+ " return target.invokeExact(@av@, filter.invokeExact()); }",
+ " protected Object invoke_Y0(@Tvav@) throws Throwable {",
+ " Object[] av = { @av@ };",
+ " filter.invokeExact(av); // make the flyby",
+ " return target.invokeExact(@av[i]@); }",
+ " }",
+ } };
+ static final String NEWLINE_INDENT = " //\n ";
+ enum VAR {
+ cat, N, P, Tvav, av, a0, a0_, _aN, Psp, av_i_;
+ public final String pattern = "@"+toString().replace('_','.')+"@";
+ public String binding = toString();
+ static void makeBindings(boolean topLevel, int inargs, int pos) {
+ assert(-1 <= pos && pos < inargs);
+ VAR.cat.binding = "F"+inargs;
+ VAR.N.binding = String.valueOf(inargs); // incoming arg count
+ VAR.P.binding = String.valueOf(pos); // selected arg position
+ String[] av = new String[inargs];
+ String[] Tvav = new String[inargs];
+ String[] av_i_ = new String[inargs];
+ for (int i = 0; i < inargs; i++) {
+ av[i] = arg(i);
+ av_i_[i] = "av["+i+"]";
+ String spc = "";
+ if (i > 0 && i % 4 == 0) spc = NEWLINE_INDENT+(pos>9?" ":"")+" ";
+ Tvav[i] = spc+param("Object", av[i]);
+ }
+ VAR.av.binding = comma(av);
+ VAR.av_i_.binding = comma(av_i_);
+ VAR.Tvav.binding = comma(Tvav);
+ if (pos >= 0) {
+ VAR.Psp.binding = (pos > 0 && pos % 10 == 0) ? NEWLINE_INDENT : "";
+ String[] a0 = new String[pos];
+ String[] aN = new String[inargs - (pos+1)];
+ for (int i = 0; i < pos; i++) {
+ String spc = "";
+ if (i > 0 && i % 10 == 0) spc = NEWLINE_INDENT;
+ a0[i] = spc+av[i];
+ }
+ VAR.a0.binding = comma(a0);
+ VAR.a0_.binding = comma(a0, ", ");
+ for (int i = pos+1; i < inargs; i++) {
+ String spc = "";
+ if (i > 0 && i % 10 == 0) spc = NEWLINE_INDENT;
+ aN[i - (pos+1)] = spc+av[i];
+ }
+ VAR._aN.binding = comma(", ", aN);
+ }
+ }
+ static String arg(int i) { return "a"+i; }
+ static String param(String t, String a) { return t+" "+a; }
+ static String comma(String[] v) { return comma(v, ""); }
+ static String comma(String[] v, String sep) { return comma("", v, sep); }
+ static String comma(String sep, String[] v) { return comma(sep, v, ""); }
+ static String comma(String sep1, String[] v, String sep2) {
+ if (v.length == 0) return "";
+ String res = v[0];
+ for (int i = 1; i < v.length; i++) res += ", "+v[i];
+ return sep1 + res + sep2;
+ }
+ static String transform(String string) {
+ for (VAR var : values())
+ string = string.replaceAll(var.pattern, var.binding);
+ return string;
+ }
+ }
+ static String[] stringsIn(String[] strings, int beg, int end) {
+ return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
+ }
+ static String[] stringsBefore(String[] strings, int pos) {
+ return stringsIn(strings, 0, pos);
+ }
+ static String[] stringsAfter(String[] strings, int pos) {
+ return stringsIn(strings, pos, strings.length);
+ }
+ static int indexAfter(String[] strings, int pos, String tag) {
+ return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
+ }
+ static int indexBefore(String[] strings, int pos, String tag) {
+ for (int i = pos, end = strings.length; ; i++) {
+ if (i == end || strings[i].endsWith(tag)) return i;
+ }
+ }
+ static int MIN_ARITY, MAX_ARITY;
+ public static void main(String... av) {
+ for (String[] template : TEMPLATES) {
+ int forLinesLimit = indexBefore(template, 0, "@each-cat@");
+ String[] forLines = stringsBefore(template, forLinesLimit);
+ template = stringsAfter(template, forLinesLimit);
+ for (String forLine : forLines)
+ expandTemplate(forLine, template);
+ }
+ }
+ static void expandTemplate(String forLine, String[] template) {
+ String[] params = forLine.split("[^0-9]+");
+ if (params[0].length() == 0) params = stringsAfter(params, 1);
+ System.out.println("//params="+Arrays.asList(params));
+ int pcur = 0;
+ MIN_ARITY = Integer.valueOf(params[pcur++]);
+ MAX_ARITY = Integer.valueOf(params[pcur++]);
+ if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
+ for (int inargs = MIN_ARITY; inargs <= MAX_ARITY; inargs++) {
+ expandTemplate(template, true, inargs, -1);
+ }
+ }
+ static void expandTemplate(String[] template, boolean topLevel, int inargs, int pos) {
+ VAR.makeBindings(topLevel, inargs, pos);
+ for (int i = 0; i < template.length; i++) {
+ String line = template[i];
+ if (line.endsWith("@each-cat@")) {
+ // ignore
+ } else if (line.endsWith("@each-P@")) {
+ int blockEnd = indexAfter(template, i, "@end-P@");
+ String[] block = stringsIn(template, i+1, blockEnd-1);
+ for (int pos1 = Math.max(0,pos); pos1 < inargs; pos1++)
+ expandTemplate(block, false, inargs, pos1);
+ VAR.makeBindings(topLevel, inargs, pos);
+ i = blockEnd-1; continue;
+ } else {
+ System.out.println(VAR.transform(line));
+ }
+ }
+ }
+}
+//}}} */
+//params=[1, 20]
+ static class F1 extends Adapter {
+ protected F1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F1(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F1 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F1(e, f, t); }
+ protected Object invoke_V0(Object a0) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0)); }
+ protected Object invoke_F0(Object a0) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0); }
+ protected Object invoke_F1(Object a0) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0); }
+ protected Object invoke_C0(Object a0) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0)); }
+ protected Object invoke_C1(Object a0) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0) throws Throwable {
+ Object[] av = { a0 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0]); }
+ }
+ static class F2 extends Adapter {
+ protected F2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F2(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F2 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F2(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1); }
+ protected Object invoke_V1(Object a0, Object a1) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1)); }
+ protected Object invoke_F0(Object a0, Object a1) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1); }
+ protected Object invoke_F1(Object a0, Object a1) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1); }
+ protected Object invoke_F2(Object a0, Object a1) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1); }
+ protected Object invoke_C0(Object a0, Object a1) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1)); }
+ protected Object invoke_C1(Object a0, Object a1) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1)); }
+ protected Object invoke_C2(Object a0, Object a1) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1) throws Throwable {
+ Object[] av = { a0, a1 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1]); }
+ }
+ static class F3 extends Adapter {
+ protected F3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F3(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F3 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F3(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2) throws Throwable {
+ Object[] av = { a0, a1, a2 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2]); }
+ }
+ static class F4 extends Adapter {
+ protected F4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F4(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F4 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F4(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ Object[] av = { a0, a1, a2, a3 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3]); }
+ }
+ static class F5 extends Adapter {
+ protected F5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F5(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F5 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F5(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4]); }
+ }
+ static class F6 extends Adapter {
+ protected F6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F6(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F6 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F6(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5]); }
+ }
+ static class F7 extends Adapter {
+ protected F7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F7(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F7 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F7(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6]); }
+ }
+ static class F8 extends Adapter {
+ protected F8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F8(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F8 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F8(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7]); }
+ }
+ static class F9 extends Adapter {
+ protected F9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F9(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F9 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F9(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8]); }
+ }
+ static class F10 extends Adapter {
+ protected F10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F10(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F10 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F10(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9]); }
+ }
+ static class F11 extends Adapter {
+ protected F11(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F11(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F11 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F11(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10]); }
+ }
+ static class F12 extends Adapter {
+ protected F12(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F12(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F12 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F12(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11]); }
+ }
+ static class F13 extends Adapter {
+ protected F13(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F13(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F13 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F13(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11, a12); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11, a12); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11, a12); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11, a12); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11), a12); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11, a12)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11, a12)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11, a12)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12]); }
+ }
+ static class F14 extends Adapter {
+ protected F14(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F14(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F14 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F14(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11, a12, a13); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11, a12, a13); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11, a12, a13); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11), a12, a13); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12), a13); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11, a12, a13)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11, a12, a13)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12, a13)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13]); }
+ }
+ static class F15 extends Adapter {
+ protected F15(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F15(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F15 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F15(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11, a12, a13, a14); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11, a12, a13, a14); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11), a12, a13, a14); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12), a13, a14); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13), a14); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11, a12, a13, a14)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11, a12, a13, a14)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12, a13, a14)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13, a14)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14]); }
+ }
+ static class F16 extends Adapter {
+ protected F16(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F16(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F16 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F16(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11, a12, a13, a14, a15); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11), a12, a13, a14, a15); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12), a13, a14, a15); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13), a14, a15); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14), a15); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11, a12, a13, a14, a15)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12, a13, a14, a15)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13, a14, a15)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14, a15)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15]); }
+ }
+ static class F17 extends Adapter {
+ protected F17(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F17(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F17 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F17(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11), a12, a13, a14, a15, a16); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12), a13, a14, a15, a16); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13), a14, a15, a16); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14), a15, a16); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15), a16); }
+ protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invokeExact(a16)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11, a12, a13, a14, a15, a16)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12, a13, a14, a15, a16)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13, a14, a15, a16)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14, a15, a16)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15, a16)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invokeExact(a16)); }
+ protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16]); }
+ }
+ static class F18 extends Adapter {
+ protected F18(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F18(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F18 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F18(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17); }
+ protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17); }
+ protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17)); }
+ protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17)); }
+ protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17]); }
+ }
+ static class F19 extends Adapter {
+ protected F19(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F19(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F19 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F19(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17, a18); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17, a18); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17, a18); }
+ protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17, a18); }
+ protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17), a18); }
+ protected Object invoke_V18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_F19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17, a18)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17, a18)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17, a18)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17, a18)); }
+ protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17, a18)); }
+ protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18)); }
+ protected Object invoke_C19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17], av[18]); }
+ }
+ static class F20 extends Adapter {
+ protected F20(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected F20(MethodHandle e, MethodHandle f, MethodHandle t) {
+ super(e, f, t); }
+ protected F20 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
+ return new F20(e, f, t); }
+ protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17, a18, a19); }
+ protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17, a18, a19); }
+ protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17, a18, a19); }
+ protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17), a18, a19); }
+ protected Object invoke_V18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18), a19); }
+ protected Object invoke_V19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact(a19)); }
+ protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_F20(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19),
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
+ protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17, a18, a19)); }
+ protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17, a18, a19)); }
+ protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17, a18, a19)); }
+ protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17, a18, a19)); }
+ protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18, a19)); }
+ protected Object invoke_C19(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact(a19)); }
+ protected Object invoke_C20(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, filter.invokeExact()); }
+ protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
+ Object a4, Object a5, Object a6, Object a7,
+ Object a8, Object a9, Object a10, Object a11,
+ Object a12, Object a13, Object a14, Object a15,
+ Object a16, Object a17, Object a18, Object a19) throws Throwable {
+ Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19 };
+ filter.invokeExact(av); // make the flyby
+ return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17], av[18], av[19]); }
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/FilterOneArgument.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/FilterOneArgument.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * Unary function composition, useful for many small plumbing jobs.
+ * The invoke method takes a single reference argument, and returns a reference
+ * Internally, it first calls the {@code filter} method on the argument,
+ * Making up the difference between the raw method type and the
+ * final method type is the responsibility of a JVM-level adapter.
+ * @author jrose
+ */
+class FilterOneArgument extends BoundMethodHandle {
+ protected final MethodHandle filter; // Object -> Object
+ protected final MethodHandle target; // Object -> Object
+
+ @Override
+ public String toString() {
+ return target.toString();
+ }
+
+ protected Object invoke(Object argument) throws Throwable {
+ Object filteredArgument = filter.invokeExact(argument);
+ return target.invokeExact(filteredArgument);
+ }
+
+ private static final MethodHandle INVOKE;
+ static {
+ try {
+ INVOKE =
+ IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke",
+ MethodType.genericMethodType(1));
+ } catch (ReflectiveOperationException ex) {
+ throw uncaughtException(ex);
+ }
+ }
+
+ protected FilterOneArgument(MethodHandle filter, MethodHandle target) {
+ super(INVOKE);
+ this.filter = filter;
+ this.target = target;
+ }
+
+ public static MethodHandle make(MethodHandle filter, MethodHandle target) {
+ if (filter == null) return target;
+ if (target == null) return filter;
+ return new FilterOneArgument(filter, target);
+ }
+
+// MethodHandle make(MethodHandle filter1, MethodHandle filter2, MethodHandle target) {
+// MethodHandle filter = make(filter1, filter2);
+// return make(filter, target);
+// }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/FromGeneric.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/FromGeneric.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.Wrapper;
+import java.lang.reflect.*;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * Adapters which mediate between incoming calls which are generic
+ * and outgoing calls which are not. Any call can be represented generically
+ * boxing up its arguments, and (on return) unboxing the return value.
+ *
+ * A call is "generic" (in MethodHandle terms) if its MethodType features
+ * only Object arguments. A non-generic call therefore features
+ * primitives and/or reference types other than Object.
+ * An adapter has types for its incoming and outgoing calls.
+ * The incoming call type is simply determined by the adapter's type
+ * (the MethodType it presents to callers). The outgoing call type
+ * is determined by the adapter's target (a MethodHandle that the adapter
+ * either binds internally or else takes as a leading argument).
+ * (To stretch the term, adapter-like method handles may have multiple
+ * targets or be polymorphic across multiple call types.)
+ * @author jrose
+ */
+class FromGeneric {
+ // type for the outgoing call (may have primitives, etc.)
+ private final MethodType targetType;
+ // type of the outgoing call internal to the adapter
+ private final MethodType internalType;
+ // prototype adapter (clone and customize for each new target!)
+ private final Adapter adapter;
+ // entry point for adapter (Adapter mh, a...) => ...
+ private final MethodHandle entryPoint;
+ // unboxing invoker of type (MH, Object**N) => raw return value
+ // it makes up the difference of internalType => targetType
+ private final MethodHandle unboxingInvoker;
+ // conversion which boxes a the target's raw return value
+ private final MethodHandle returnConversion;
+
+ /** Compute and cache information common to all unboxing adapters
+ * that can call out to targets of the erasure-family of the given erased type.
+ */
+ private FromGeneric(MethodType targetType) {
+ this.targetType = targetType;
+ MethodType internalType0;
+ // the target invoker will generally need casts on reference arguments
+ Adapter ad = findAdapter(internalType0 = targetType.erase());
+ if (ad != null) {
+ // Immediate hit to exactly the adapter we want,
+ // with no monkeying around with primitive types.
+ this.internalType = internalType0;
+ this.adapter = ad;
+ this.entryPoint = ad.prototypeEntryPoint();
+ this.returnConversion = computeReturnConversion(targetType, internalType0);
+ this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
+ return;
+ }
+
+ // outgoing primitive arguments will be wrapped; unwrap them
+ MethodType primsAsObj = targetType.form().primArgsAsBoxes();
+ MethodType objArgsRawRet = primsAsObj.form().primsAsInts();
+ if (objArgsRawRet != targetType)
+ ad = findAdapter(internalType0 = objArgsRawRet);
+ if (ad == null) {
+ ad = buildAdapterFromBytecodes(internalType0 = targetType);
+ }
+ this.internalType = internalType0;
+ this.adapter = ad;
+ MethodType tepType = targetType.insertParameterTypes(0, adapter.getClass());
+ this.entryPoint = ad.prototypeEntryPoint();
+ this.returnConversion = computeReturnConversion(targetType, internalType0);
+ this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
+ }
+
+ /**
+ * The typed target will be called according to targetType.
+ * The adapter code will in fact see the raw result from internalType,
+ * and must box it into an object. Produce a converter for this.
+ */
+ private static MethodHandle computeReturnConversion(
+ MethodType targetType, MethodType internalType) {
+ Class> tret = targetType.returnType();
+ Class> iret = internalType.returnType();
+ Wrapper wrap = Wrapper.forBasicType(tret);
+ if (!iret.isPrimitive()) {
+ assert(iret == Object.class);
+ return ValueConversions.identity();
+ } else if (wrap.primitiveType() == iret) {
+ return ValueConversions.box(wrap, false);
+ } else {
+ assert(tret == double.class ? iret == long.class : iret == int.class);
+ return ValueConversions.boxRaw(wrap, false);
+ }
+ }
+
+ /**
+ * The typed target will need an exact invocation point; provide it here.
+ * The adapter will possibly need to make a slightly different call,
+ * so adapt the invoker. This way, the logic for making up the
+ * difference between what the adapter can call and what the target
+ * needs can be cached once per type.
+ */
+ private static MethodHandle computeUnboxingInvoker(
+ MethodType targetType, MethodType internalType) {
+ // All the adapters we have here have reference-untyped internal calls.
+ assert(internalType == internalType.erase());
+ MethodHandle invoker = targetType.invokers().exactInvoker();
+ // cast all narrow reference types, unbox all primitive arguments:
+ MethodType fixArgsType = internalType.changeReturnType(targetType.returnType());
+ MethodHandle fixArgs = MethodHandleImpl.convertArguments(
+ invoker, Invokers.invokerType(fixArgsType),
+ invoker.type(), null);
+ if (fixArgs == null)
+ throw new InternalError("bad fixArgs");
+ // reinterpret the calling sequence as raw:
+ MethodHandle retyper = AdapterMethodHandle.makeRetypeRaw(
+ Invokers.invokerType(internalType), fixArgs);
+ if (retyper == null)
+ throw new InternalError("bad retyper");
+ return retyper;
+ }
+
+ Adapter makeInstance(MethodHandle typedTarget) {
+ MethodType type = typedTarget.type();
+ if (type == targetType) {
+ return adapter.makeInstance(entryPoint, unboxingInvoker, returnConversion, typedTarget);
+ }
+ // my erased-type is not exactly the same as the desired type
+ assert(type.erase() == targetType); // else we are busted
+ MethodHandle invoker = computeUnboxingInvoker(type, internalType);
+ return adapter.makeInstance(entryPoint, invoker, returnConversion, typedTarget);
+ }
+
+ /** Build an adapter of the given generic type, which invokes typedTarget
+ * on the incoming arguments, after unboxing as necessary.
+ * The return value is boxed if necessary.
+ * @param genericType the required type of the result
+ * @param typedTarget the target
+ * @return an adapter method handle
+ */
+ public static MethodHandle make(MethodHandle typedTarget) {
+ MethodType type = typedTarget.type();
+ if (type == type.generic()) return typedTarget;
+ return FromGeneric.of(type).makeInstance(typedTarget);
+ }
+
+ /** Return the adapter information for this type's erasure. */
+ static FromGeneric of(MethodType type) {
+ MethodTypeForm form = type.form();
+ FromGeneric fromGen = form.fromGeneric;
+ if (fromGen == null)
+ form.fromGeneric = fromGen = new FromGeneric(form.erasedType());
+ return fromGen;
+ }
+
+ public String toString() {
+ return "FromGeneric"+targetType;
+ }
+
+ /* Create an adapter that handles spreading calls for the given type. */
+ static Adapter findAdapter(MethodType internalType) {
+ MethodType entryType = internalType.generic();
+ MethodTypeForm form = internalType.form();
+ Class> rtype = internalType.returnType();
+ int argc = form.parameterCount();
+ int lac = form.longPrimitiveParameterCount();
+ int iac = form.primitiveParameterCount() - lac;
+ String intsAndLongs = (iac > 0 ? "I"+iac : "")+(lac > 0 ? "J"+lac : "");
+ String rawReturn = String.valueOf(Wrapper.forPrimitiveType(rtype).basicTypeChar());
+ String cname0 = rawReturn + argc;
+ String cname1 = "A" + argc;
+ String[] cnames = { cname0+intsAndLongs, cname0, cname1+intsAndLongs, cname1 };
+ String iname = "invoke_"+cname0+intsAndLongs;
+ // e.g., D5I2, D5, L5I2, L5; invoke_D5
+ for (String cname : cnames) {
+ Class extends Adapter> acls = Adapter.findSubClass(cname);
+ if (acls == null) continue;
+ // see if it has the required invoke method
+ MethodHandle entryPoint = null;
+ try {
+ entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
+ } catch (ReflectiveOperationException ex) {
+ }
+ if (entryPoint == null) continue;
+ Constructor extends Adapter> ctor = null;
+ try {
+ ctor = acls.getDeclaredConstructor(MethodHandle.class);
+ } catch (NoSuchMethodException ex) {
+ } catch (SecurityException ex) {
+ }
+ if (ctor == null) continue;
+ try {
+ // Produce an instance configured as a prototype.
+ return ctor.newInstance(entryPoint);
+ } catch (IllegalArgumentException ex) {
+ } catch (InvocationTargetException wex) {
+ Throwable ex = wex.getTargetException();
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ } catch (InstantiationException ex) {
+ } catch (IllegalAccessException ex) {
+ }
+ }
+ return null;
+ }
+
+ static Adapter buildAdapterFromBytecodes(MethodType internalType) {
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ /**
+ * This adapter takes some untyped arguments, and returns an untyped result.
+ * Internally, it applies the invoker to the target, which causes the
+ * objects to be unboxed; the result is a raw type in L/I/J/F/D.
+ * This result is passed to convert, which is responsible for
+ * converting the raw result into a boxed object.
+ * The invoker is kept separate from the target because it can be
+ * generated once per type erasure family, and reused across adapters.
+ */
+ static abstract class Adapter extends BoundMethodHandle {
+ /*
+ * class X<> extends Adapter {
+ * (MH, Object**N)=>raw(R) invoker;
+ * (any**N)=>R target;
+ * raw(R)=>Object convert;
+ * Object invoke(Object**N a) = convert(invoker(target, a...))
+ * }
+ */
+ protected final MethodHandle invoker; // (MH, Object**N) => raw(R)
+ protected final MethodHandle convert; // raw(R) => Object
+ protected final MethodHandle target; // (any**N) => R
+
+ @Override
+ public String toString() {
+ return addTypeString(target, this);
+ }
+
+ protected boolean isPrototype() { return target == null; }
+ protected Adapter(MethodHandle entryPoint) {
+ this(entryPoint, null, entryPoint, null);
+ assert(isPrototype());
+ }
+ protected MethodHandle prototypeEntryPoint() {
+ if (!isPrototype()) throw new InternalError();
+ return convert;
+ }
+
+ protected Adapter(MethodHandle entryPoint,
+ MethodHandle invoker, MethodHandle convert, MethodHandle target) {
+ super(entryPoint);
+ this.invoker = invoker;
+ this.convert = convert;
+ this.target = target;
+ }
+
+ /** Make a copy of self, with new fields. */
+ protected abstract Adapter makeInstance(MethodHandle entryPoint,
+ MethodHandle invoker, MethodHandle convert, MethodHandle target);
+ // { return new ThisType(entryPoint, convert, target); }
+
+ /// Conversions on the value returned from the target.
+ protected Object convert_L(Object result) throws Throwable { return convert.invokeExact(result); }
+ protected Object convert_I(int result) throws Throwable { return convert.invokeExact(result); }
+ protected Object convert_J(long result) throws Throwable { return convert.invokeExact(result); }
+ protected Object convert_F(float result) throws Throwable { return convert.invokeExact(result); }
+ protected Object convert_D(double result) throws Throwable { return convert.invokeExact(result); }
+
+ static private final String CLASS_PREFIX; // "java.lang.invoke.FromGeneric$"
+ static {
+ String aname = Adapter.class.getName();
+ String sname = Adapter.class.getSimpleName();
+ if (!aname.endsWith(sname)) throw new InternalError();
+ CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
+ }
+ /** Find a sibing class of Adapter. */
+ static Class extends Adapter> findSubClass(String name) {
+ String cname = Adapter.CLASS_PREFIX + name;
+ try {
+ return Class.forName(cname).asSubclass(Adapter.class);
+ } catch (ClassNotFoundException ex) {
+ return null;
+ } catch (ClassCastException ex) {
+ return null;
+ }
+ }
+ }
+
+ /* generated classes follow this pattern:
+ static class xA2 extends Adapter {
+ protected xA2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected xA2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected xA2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new xA2(e, i, c, t); }
+ protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1)); }
+ protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1)); }
+ protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1)); }
+ protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1)); }
+ protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1)); }
+ }
+ // */
+
+/*
+: SHELL; n=FromGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
+//{{{
+import java.util.*;
+class genclasses {
+ static String[] TYPES = { "Object", "int ", "long ", "float ", "double" };
+ static String[] WRAPS = { " ", "(Integer)", "(Long) ", "(Float) ", "(Double) " };
+ static String[] TCHARS = { "L", "I", "J", "F", "D", "A" };
+ static String[][] TEMPLATES = { {
+ "@for@ arity=0..10 rcat<=4 nrefs<=99 nints=0 nlongs=0",
+ " //@each-cat@",
+ " static class @cat@ extends Adapter {",
+ " protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
+ " protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
+ " { super(e, i, c, t); }",
+ " protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
+ " { return new @cat@(e, i, c, t); }",
+ " //@each-R@",
+ " protected Object invoke_@catN@(@Tvav@) throws Throwable { return convert_@Rc@((@R@)@W@invoker.invokeExact(target@av@)); }",
+ " //@end-R@",
+ " }",
+ } };
+ static final String NEWLINE_INDENT = "\n ";
+ enum VAR {
+ cat, catN, R, Rc, W, av, Tvav, Ovav;
+ public final String pattern = "@"+toString().replace('_','.')+"@";
+ public String binding;
+ static void makeBindings(boolean topLevel, int rcat, int nrefs, int nints, int nlongs) {
+ int nargs = nrefs + nints + nlongs;
+ if (topLevel)
+ VAR.cat.binding = catstr(ALL_RETURN_TYPES ? TYPES.length : rcat, nrefs, nints, nlongs);
+ VAR.catN.binding = catstr(rcat, nrefs, nints, nlongs);
+ VAR.R.binding = TYPES[rcat];
+ VAR.Rc.binding = TCHARS[rcat];
+ VAR.W.binding = WRAPS[rcat];
+ String[] Tv = new String[nargs];
+ String[] av = new String[nargs];
+ String[] Tvav = new String[nargs];
+ String[] Ovav = new String[nargs];
+ for (int i = 0; i < nargs; i++) {
+ int tcat = (i < nrefs) ? 0 : (i < nrefs + nints) ? 1 : 2;
+ Tv[i] = TYPES[tcat];
+ av[i] = arg(i);
+ Tvav[i] = param(Tv[i], av[i]);
+ Ovav[i] = param("Object", av[i]);
+ }
+ VAR.av.binding = comma(", ", av);
+ VAR.Tvav.binding = comma(Tvav);
+ VAR.Ovav.binding = comma(Ovav);
+ }
+ static String arg(int i) { return "a"+i; }
+ static String param(String t, String a) { return t+" "+a; }
+ static String comma(String[] v) { return comma("", v); }
+ static String comma(String sep, String[] v) {
+ if (v.length == 0) return "";
+ String res = sep+v[0];
+ for (int i = 1; i < v.length; i++) res += ", "+v[i];
+ return res;
+ }
+ static String transform(String string) {
+ for (VAR var : values())
+ string = string.replaceAll(var.pattern, var.binding);
+ return string;
+ }
+ }
+ static String[] stringsIn(String[] strings, int beg, int end) {
+ return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
+ }
+ static String[] stringsBefore(String[] strings, int pos) {
+ return stringsIn(strings, 0, pos);
+ }
+ static String[] stringsAfter(String[] strings, int pos) {
+ return stringsIn(strings, pos, strings.length);
+ }
+ static int indexAfter(String[] strings, int pos, String tag) {
+ return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
+ }
+ static int indexBefore(String[] strings, int pos, String tag) {
+ for (int i = pos, end = strings.length; ; i++) {
+ if (i == end || strings[i].endsWith(tag)) return i;
+ }
+ }
+ static int MIN_ARITY, MAX_ARITY, MAX_RCAT, MAX_REFS, MAX_INTS, MAX_LONGS;
+ static boolean ALL_ARG_TYPES, ALL_RETURN_TYPES;
+ static HashSet done = new HashSet();
+ public static void main(String... av) {
+ for (String[] template : TEMPLATES) {
+ int forLinesLimit = indexBefore(template, 0, "@each-cat@");
+ String[] forLines = stringsBefore(template, forLinesLimit);
+ template = stringsAfter(template, forLinesLimit);
+ for (String forLine : forLines)
+ expandTemplate(forLine, template);
+ }
+ }
+ static void expandTemplate(String forLine, String[] template) {
+ String[] params = forLine.split("[^0-9]+");
+ if (params[0].length() == 0) params = stringsAfter(params, 1);
+ System.out.println("//params="+Arrays.asList(params));
+ int pcur = 0;
+ MIN_ARITY = Integer.valueOf(params[pcur++]);
+ MAX_ARITY = Integer.valueOf(params[pcur++]);
+ MAX_RCAT = Integer.valueOf(params[pcur++]);
+ MAX_REFS = Integer.valueOf(params[pcur++]);
+ MAX_INTS = Integer.valueOf(params[pcur++]);
+ MAX_LONGS = Integer.valueOf(params[pcur++]);
+ if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
+ if (MAX_RCAT >= TYPES.length) MAX_RCAT = TYPES.length - 1;
+ ALL_ARG_TYPES = (indexBefore(template, 0, "@each-Tv@") < template.length);
+ ALL_RETURN_TYPES = (indexBefore(template, 0, "@each-R@") < template.length);
+ for (int nargs = MIN_ARITY; nargs <= MAX_ARITY; nargs++) {
+ for (int rcat = 0; rcat <= MAX_RCAT; rcat++) {
+ expandTemplate(template, true, rcat, nargs, 0, 0);
+ if (ALL_ARG_TYPES) break;
+ expandTemplateForPrims(template, true, rcat, nargs, 1, 1);
+ if (ALL_RETURN_TYPES) break;
+ }
+ }
+ }
+ static String catstr(int rcat, int nrefs, int nints, int nlongs) {
+ int nargs = nrefs + nints + nlongs;
+ String cat = TCHARS[rcat] + nargs;
+ if (!ALL_ARG_TYPES) cat += (nints==0?"":"I"+nints)+(nlongs==0?"":"J"+nlongs);
+ return cat;
+ }
+ static void expandTemplateForPrims(String[] template, boolean topLevel, int rcat, int nargs, int minints, int minlongs) {
+ for (int isLong = 0; isLong <= 1; isLong++) {
+ for (int nprims = 1; nprims <= nargs; nprims++) {
+ int nrefs = nargs - nprims;
+ int nints = ((1-isLong) * nprims);
+ int nlongs = (isLong * nprims);
+ expandTemplate(template, topLevel, rcat, nrefs, nints, nlongs);
+ }
+ }
+ }
+ static void expandTemplate(String[] template, boolean topLevel,
+ int rcat, int nrefs, int nints, int nlongs) {
+ int nargs = nrefs + nints + nlongs;
+ if (nrefs > MAX_REFS || nints > MAX_INTS || nlongs > MAX_LONGS) return;
+ VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
+ if (topLevel && !done.add(VAR.cat.binding)) {
+ System.out.println(" //repeat "+VAR.cat.binding);
+ return;
+ }
+ for (int i = 0; i < template.length; i++) {
+ String line = template[i];
+ if (line.endsWith("@each-cat@")) {
+ // ignore
+ } else if (line.endsWith("@each-R@")) {
+ int blockEnd = indexAfter(template, i, "@end-R@");
+ String[] block = stringsIn(template, i+1, blockEnd-1);
+ for (int rcat1 = rcat; rcat1 <= MAX_RCAT; rcat1++)
+ expandTemplate(block, false, rcat1, nrefs, nints, nlongs);
+ VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
+ i = blockEnd-1; continue;
+ } else if (line.endsWith("@each-Tv@")) {
+ int blockEnd = indexAfter(template, i, "@end-Tv@");
+ String[] block = stringsIn(template, i+1, blockEnd-1);
+ expandTemplate(block, false, rcat, nrefs, nints, nlongs);
+ expandTemplateForPrims(block, false, rcat, nargs, nints+1, nlongs+1);
+ VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
+ i = blockEnd-1; continue;
+ } else {
+ System.out.println(VAR.transform(line));
+ }
+ }
+ }
+}
+//}}} */
+//params=[0, 10, 4, 99, 0, 0]
+ static class A0 extends Adapter {
+ protected A0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A0(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A0(e, i, c, t); }
+ protected Object invoke_L0() throws Throwable { return convert_L((Object)invoker.invokeExact(target)); }
+ protected Object invoke_I0() throws Throwable { return convert_I((int) invoker.invokeExact(target)); }
+ protected Object invoke_J0() throws Throwable { return convert_J((long) invoker.invokeExact(target)); }
+ protected Object invoke_F0() throws Throwable { return convert_F((float) invoker.invokeExact(target)); }
+ protected Object invoke_D0() throws Throwable { return convert_D((double)invoker.invokeExact(target)); }
+ }
+ static class A1 extends Adapter {
+ protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A1(e, i, c, t); }
+ protected Object invoke_L1(Object a0) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0)); }
+ protected Object invoke_I1(Object a0) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0)); }
+ protected Object invoke_J1(Object a0) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0)); }
+ protected Object invoke_F1(Object a0) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0)); }
+ protected Object invoke_D1(Object a0) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0)); }
+ }
+ static class A2 extends Adapter {
+ protected A2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A2(e, i, c, t); }
+ protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1)); }
+ protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1)); }
+ protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1)); }
+ protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1)); }
+ protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1)); }
+ }
+ static class A3 extends Adapter {
+ protected A3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A3(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A3 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A3(e, i, c, t); }
+ protected Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2)); }
+ protected Object invoke_I3(Object a0, Object a1, Object a2) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2)); }
+ protected Object invoke_J3(Object a0, Object a1, Object a2) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2)); }
+ protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2)); }
+ protected Object invoke_D3(Object a0, Object a1, Object a2) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2)); }
+ }
+ static class A4 extends Adapter {
+ protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A4(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A4 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A4(e, i, c, t); }
+ protected Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3)); }
+ protected Object invoke_I4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3)); }
+ protected Object invoke_J4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3)); }
+ protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3)); }
+ protected Object invoke_D4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3)); }
+ }
+ static class A5 extends Adapter {
+ protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A5(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A5 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A5(e, i, c, t); }
+ protected Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_I5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_J5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
+ protected Object invoke_D5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
+ }
+ static class A6 extends Adapter {
+ protected A6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A6(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A6 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A6(e, i, c, t); }
+ protected Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_I6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_J6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_D6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
+ }
+ static class A7 extends Adapter {
+ protected A7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A7(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A7 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A7(e, i, c, t); }
+ protected Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_I7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_J7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_D7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
+ }
+ static class A8 extends Adapter {
+ protected A8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A8(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A8 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A8(e, i, c, t); }
+ protected Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_I8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_J8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_D8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
+ }
+ static class A9 extends Adapter {
+ protected A9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A9(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A9 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A9(e, i, c, t); }
+ protected Object invoke_L9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_I9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_J9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_D9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ }
+ static class A10 extends Adapter {
+ protected A10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A10(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { super(e, i, c, t); }
+ protected A10 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
+ { return new A10(e, i, c, t); }
+ protected Object invoke_L10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_I10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_J10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_D10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/InvokeDynamic.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/InvokeDynamic.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+/**
+ * This is a place-holder class. Some HotSpot implementations need to see it.
+ */
+final class InvokeDynamic {
+ private InvokeDynamic() { throw new InternalError(); } // do not instantiate
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2009, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * Adapters which manage MethodHandle.invokeGeneric calls.
+ * The JVM calls one of these when the exact type match fails.
+ * @author jrose
+ */
+class InvokeGeneric {
+ // erased type for the call, which originates from an invokeGeneric site
+ private final MethodType erasedCallerType;
+ // an invoker of type (MT, MH; A...) -> R
+ private final MethodHandle initialInvoker;
+
+ /** Compute and cache information for this adapter, so that it can
+ * call out to targets of the erasure-family of the given erased type.
+ */
+ /*non-public*/ InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException {
+ assert(erasedCallerType.equals(erasedCallerType.erase()));
+ this.erasedCallerType = erasedCallerType;
+ this.initialInvoker = makeInitialInvoker();
+ assert initialInvoker.type().equals(erasedCallerType
+ .insertParameterTypes(0, MethodType.class, MethodHandle.class))
+ : initialInvoker.type();
+ }
+
+ private static MethodHandles.Lookup lookup() {
+ return IMPL_LOOKUP;
+ }
+
+ /** Return the adapter information for this type's erasure. */
+ /*non-public*/ static MethodHandle genericInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException {
+ InvokeGeneric gen = new InvokeGeneric(erasedCallerType);
+ return gen.initialInvoker;
+ }
+
+ private MethodHandle makeInitialInvoker() throws ReflectiveOperationException {
+ // postDispatch = #(MH'; MT, MH; A...){MH'(MT, MH; A)}
+ MethodHandle postDispatch = makePostDispatchInvoker();
+ MethodHandle invoker;
+ if (returnConversionPossible()) {
+ invoker = MethodHandles.foldArguments(postDispatch,
+ dispatcher("dispatchWithConversion"));
+ } else {
+ invoker = MethodHandles.foldArguments(postDispatch, dispatcher("dispatch"));
+ }
+ return invoker;
+ }
+
+ private static final Class>[] EXTRA_ARGS = { MethodType.class, MethodHandle.class };
+ private MethodHandle makePostDispatchInvoker() {
+ // Take (MH'; MT, MH; A...) and run MH'(MT, MH; A...).
+ MethodType invokerType = erasedCallerType.insertParameterTypes(0, EXTRA_ARGS);
+ return invokerType.invokers().exactInvoker();
+ }
+ private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) {
+ assert(targetInvoker.type().parameterType(0) == MethodHandle.class);
+ return MethodHandles.dropArguments(targetInvoker, 1, EXTRA_ARGS);
+ }
+
+ private MethodHandle dispatcher(String dispatchName) throws ReflectiveOperationException {
+ return lookup().bind(this, dispatchName,
+ MethodType.methodType(MethodHandle.class,
+ MethodType.class, MethodHandle.class));
+ }
+
+ static final boolean USE_AS_TYPE_PATH = true;
+
+ /** Return a method handle to invoke on the callerType, target, and remaining arguments.
+ * The method handle must finish the call.
+ * This is the first look at the caller type and target.
+ */
+ private MethodHandle dispatch(MethodType callerType, MethodHandle target) {
+ MethodType targetType = target.type();
+ if (USE_AS_TYPE_PATH || target.isVarargsCollector()) {
+ MethodHandle newTarget = target.asType(callerType);
+ targetType = callerType;
+ Invokers invokers = targetType.invokers();
+ MethodHandle invoker = invokers.erasedInvokerWithDrops;
+ if (invoker == null) {
+ invokers.erasedInvokerWithDrops = invoker =
+ dropDispatchArguments(invokers.erasedInvoker());
+ }
+ return invoker.bindTo(newTarget);
+ }
+ throw new RuntimeException("NYI");
+ }
+
+ private MethodHandle dispatchWithConversion(MethodType callerType, MethodHandle target) {
+ MethodHandle finisher = dispatch(callerType, target);
+ if (returnConversionNeeded(callerType, target))
+ finisher = addReturnConversion(finisher, callerType.returnType()); //FIXME: slow
+ return finisher;
+ }
+
+ private boolean returnConversionPossible() {
+ Class> needType = erasedCallerType.returnType();
+ return !needType.isPrimitive();
+ }
+ private boolean returnConversionNeeded(MethodType callerType, MethodHandle target) {
+ Class> needType = callerType.returnType();
+ if (needType == erasedCallerType.returnType())
+ return false; // no conversions possible, since must be primitive or Object
+ Class> haveType = target.type().returnType();
+ if (VerifyType.isNullConversion(haveType, needType))
+ return false;
+ return true;
+ }
+ private MethodHandle addReturnConversion(MethodHandle target, Class> type) {
+ if (true) throw new RuntimeException("NYI");
+ // FIXME: This is slow because it creates a closure node on every call that requires a return cast.
+ MethodType targetType = target.type();
+ MethodHandle caster = ValueConversions.identity(type);
+ caster = caster.asType(MethodType.methodType(type, targetType.returnType()));
+ // Drop irrelevant arguments, because we only care about the return value:
+ caster = MethodHandles.dropArguments(caster, 1, targetType.parameterList());
+ MethodHandle result = MethodHandles.foldArguments(caster, target);
+ return result.asType(target.type());
+ }
+
+ public String toString() {
+ return "InvokeGeneric"+erasedCallerType;
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/Invokers.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.empty.Empty;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * Construction and caching of often-used invokers.
+ * @author jrose
+ */
+class Invokers {
+ // exact type (sans leading taget MH) for the outgoing call
+ private final MethodType targetType;
+
+ // exact invoker for the outgoing call
+ private /*lazy*/ MethodHandle exactInvoker;
+
+ // erased (partially untyped but with primitives) invoker for the outgoing call
+ private /*lazy*/ MethodHandle erasedInvoker;
+ /*lazy*/ MethodHandle erasedInvokerWithDrops; // for InvokeGeneric
+
+ // generic (untyped) invoker for the outgoing call
+ private /*lazy*/ MethodHandle genericInvoker;
+
+ // generic (untyped) invoker for the outgoing call; accepts a single Object[]
+ private final /*lazy*/ MethodHandle[] spreadInvokers;
+
+ // invoker for an unbound callsite
+ private /*lazy*/ MethodHandle uninitializedCallSite;
+
+ /** Compute and cache information common to all collecting adapters
+ * that implement members of the erasure-family of the given erased type.
+ */
+ /*non-public*/ Invokers(MethodType targetType) {
+ this.targetType = targetType;
+ this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1];
+ }
+
+ /*non-public*/ static MethodType invokerType(MethodType targetType) {
+ return targetType.insertParameterTypes(0, MethodHandle.class);
+ }
+
+ /*non-public*/ MethodHandle exactInvoker() {
+ MethodHandle invoker = exactInvoker;
+ if (invoker != null) return invoker;
+ try {
+ invoker = IMPL_LOOKUP.findVirtual(MethodHandle.class, "invokeExact", targetType);
+ } catch (ReflectiveOperationException ex) {
+ throw new InternalError("JVM cannot find invoker for "+targetType);
+ }
+ assert(invokerType(targetType) == invoker.type());
+ exactInvoker = invoker;
+ return invoker;
+ }
+
+ /*non-public*/ MethodHandle genericInvoker() {
+ MethodHandle invoker1 = exactInvoker();
+ MethodHandle invoker = genericInvoker;
+ if (invoker != null) return invoker;
+ MethodType genericType = targetType.generic();
+ invoker = MethodHandles.convertArguments(invoker1, invokerType(genericType));
+ genericInvoker = invoker;
+ return invoker;
+ }
+
+ /*non-public*/ MethodHandle erasedInvoker() {
+ MethodHandle invoker1 = exactInvoker();
+ MethodHandle invoker = erasedInvoker;
+ if (invoker != null) return invoker;
+ MethodType erasedType = targetType.erase();
+ if (erasedType == targetType.generic())
+ invoker = genericInvoker();
+ else
+ invoker = MethodHandles.convertArguments(invoker1, invokerType(erasedType));
+ erasedInvoker = invoker;
+ return invoker;
+ }
+
+ /*non-public*/ MethodHandle spreadInvoker(int objectArgCount) {
+ MethodHandle vaInvoker = spreadInvokers[objectArgCount];
+ if (vaInvoker != null) return vaInvoker;
+ MethodHandle gInvoker = genericInvoker();
+ vaInvoker = gInvoker.asSpreader(Object[].class, targetType.parameterCount() - objectArgCount);
+ spreadInvokers[objectArgCount] = vaInvoker;
+ return vaInvoker;
+ }
+
+ private static MethodHandle THROW_UCS = null;
+
+ /*non-public*/ MethodHandle uninitializedCallSite() {
+ MethodHandle invoker = uninitializedCallSite;
+ if (invoker != null) return invoker;
+ if (targetType.parameterCount() > 0) {
+ MethodType type0 = targetType.dropParameterTypes(0, targetType.parameterCount());
+ Invokers invokers0 = type0.invokers();
+ invoker = MethodHandles.dropArguments(invokers0.uninitializedCallSite(),
+ 0, targetType.parameterList());
+ assert(invoker.type().equals(targetType));
+ uninitializedCallSite = invoker;
+ return invoker;
+ }
+ if (THROW_UCS == null) {
+ try {
+ THROW_UCS = IMPL_LOOKUP
+ .findStatic(CallSite.class, "uninitializedCallSite",
+ MethodType.methodType(Empty.class));
+ } catch (ReflectiveOperationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ invoker = AdapterMethodHandle.makeRetypeRaw(targetType, THROW_UCS);
+ assert(invoker.type().equals(targetType));
+ uninitializedCallSite = invoker;
+ return invoker;
+ }
+
+ public String toString() {
+ return "Invokers"+targetType;
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MemberName.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,718 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.BytecodeDescriptor;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A {@code MemberName} is a compact symbolic datum which fully characterizes
+ * a method or field reference.
+ * A member name refers to a field, method, constructor, or member type.
+ * Every member name has a simple name (a string) and a type (either a Class or MethodType).
+ * A member name may also have a non-null declaring class, or it may be simply
+ * a naked name/type pair.
+ * A member name may also have non-zero modifier flags.
+ * Finally, a member name may be either resolved or unresolved.
+ * If it is resolved, the existence of the named
+ *
+ * Whether resolved or not, a member name provides no access rights or
+ * invocation capability to its possessor. It is merely a compact
+ * representation of all symbolic information necessary to link to
+ * and properly use the named member.
+ *
+ * When resolved, a member name's internal implementation may include references to JVM metadata.
+ * This representation is stateless and only decriptive.
+ * It provides no private information and no capability to use the member.
+ *
+ * By contrast, a {@linkplain java.lang.reflect.Method} contains fuller information
+ * about the internals of a method (except its bytecodes) and also
+ * allows invocation. A MemberName is much lighter than a Method,
+ * since it contains about 7 fields to the 16 of Method (plus its sub-arrays),
+ * and those seven fields omit much of the information in Method.
+ * @author jrose
+ */
+/*non-public*/ final class MemberName implements Member, Cloneable {
+ private Class> clazz; // class in which the method is defined
+ private String name; // may be null if not yet materialized
+ private Object type; // may be null if not yet materialized
+ private int flags; // modifier bits; see reflect.Modifier
+
+ private Object vmtarget; // VM-specific target value
+ private int vmindex; // method index within class or interface
+
+ { vmindex = VM_INDEX_UNINITIALIZED; }
+
+ /** Return the declaring class of this member.
+ * In the case of a bare name and type, the declaring class will be null.
+ */
+ public Class> getDeclaringClass() {
+ if (clazz == null && isResolved()) {
+ expandFromVM();
+ }
+ return clazz;
+ }
+
+ /** Utility method producing the class loader of the declaring class. */
+ public ClassLoader getClassLoader() {
+ return clazz.getClassLoader();
+ }
+
+ /** Return the simple name of this member.
+ * For a type, it is the same as {@link Class#getSimpleName}.
+ * For a method or field, it is the simple name of the member.
+ * For a constructor, it is always {@code "<init>"}.
+ */
+ public String getName() {
+ if (name == null) {
+ expandFromVM();
+ if (name == null) return null;
+ }
+ return name;
+ }
+
+ /** Return the declared type of this member, which
+ * must be a method or constructor.
+ */
+ public MethodType getMethodType() {
+ if (type == null) {
+ expandFromVM();
+ if (type == null) return null;
+ }
+ if (!isInvocable())
+ throw newIllegalArgumentException("not invocable, no method type");
+ if (type instanceof MethodType) {
+ return (MethodType) type;
+ }
+ if (type instanceof String) {
+ String sig = (String) type;
+ MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
+ this.type = res;
+ return res;
+ }
+ if (type instanceof Object[]) {
+ Object[] typeInfo = (Object[]) type;
+ Class>[] ptypes = (Class>[]) typeInfo[1];
+ Class> rtype = (Class>) typeInfo[0];
+ MethodType res = MethodType.methodType(rtype, ptypes);
+ this.type = res;
+ return res;
+ }
+ throw new InternalError("bad method type "+type);
+ }
+
+ /** Return the actual type under which this method or constructor must be invoked.
+ * For non-static methods or constructors, this is the type with a leading parameter,
+ * a reference to declaring class. For static methods, it is the same as the declared type.
+ */
+ public MethodType getInvocationType() {
+ MethodType itype = getMethodType();
+ if (!isStatic())
+ itype = itype.insertParameterTypes(0, clazz);
+ return itype;
+ }
+
+ /** Utility method producing the parameter types of the method type. */
+ public Class>[] getParameterTypes() {
+ return getMethodType().parameterArray();
+ }
+
+ /** Utility method producing the return type of the method type. */
+ public Class> getReturnType() {
+ return getMethodType().returnType();
+ }
+
+ /** Return the declared type of this member, which
+ * must be a field or type.
+ * If it is a type member, that type itself is returned.
+ */
+ public Class> getFieldType() {
+ if (type == null) {
+ expandFromVM();
+ if (type == null) return null;
+ }
+ if (isInvocable())
+ throw newIllegalArgumentException("not a field or nested class, no simple type");
+ if (type instanceof Class>) {
+ return (Class>) type;
+ }
+ if (type instanceof String) {
+ String sig = (String) type;
+ MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
+ Class> res = mtype.returnType();
+ this.type = res;
+ return res;
+ }
+ throw new InternalError("bad field type "+type);
+ }
+
+ /** Utility method to produce either the method type or field type of this member. */
+ public Object getType() {
+ return (isInvocable() ? getMethodType() : getFieldType());
+ }
+
+ /** Utility method to produce the signature of this member,
+ * used within the class file format to describe its type.
+ */
+ public String getSignature() {
+ if (type == null) {
+ expandFromVM();
+ if (type == null) return null;
+ }
+ if (type instanceof String)
+ return (String) type;
+ if (isInvocable())
+ return BytecodeDescriptor.unparse(getMethodType());
+ else
+ return BytecodeDescriptor.unparse(getFieldType());
+ }
+
+ /** Return the modifier flags of this member.
+ * @see java.lang.reflect.Modifier
+ */
+ public int getModifiers() {
+ return (flags & RECOGNIZED_MODIFIERS);
+ }
+
+ private void setFlags(int flags) {
+ this.flags = flags;
+ assert(testAnyFlags(ALL_KINDS));
+ }
+
+ private boolean testFlags(int mask, int value) {
+ return (flags & mask) == value;
+ }
+ private boolean testAllFlags(int mask) {
+ return testFlags(mask, mask);
+ }
+ private boolean testAnyFlags(int mask) {
+ return !testFlags(mask, 0);
+ }
+
+ /** Utility method to query the modifier flags of this member. */
+ public boolean isStatic() {
+ return Modifier.isStatic(flags);
+ }
+ /** Utility method to query the modifier flags of this member. */
+ public boolean isPublic() {
+ return Modifier.isPublic(flags);
+ }
+ /** Utility method to query the modifier flags of this member. */
+ public boolean isPrivate() {
+ return Modifier.isPrivate(flags);
+ }
+ /** Utility method to query the modifier flags of this member. */
+ public boolean isProtected() {
+ return Modifier.isProtected(flags);
+ }
+ /** Utility method to query the modifier flags of this member. */
+ public boolean isFinal() {
+ return Modifier.isFinal(flags);
+ }
+ /** Utility method to query the modifier flags of this member. */
+ public boolean isAbstract() {
+ return Modifier.isAbstract(flags);
+ }
+ // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
+
+ // unofficial modifier flags, used by HotSpot:
+ static final int BRIDGE = 0x00000040;
+ static final int VARARGS = 0x00000080;
+ static final int SYNTHETIC = 0x00001000;
+ static final int ANNOTATION= 0x00002000;
+ static final int ENUM = 0x00004000;
+ /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
+ public boolean isBridge() {
+ return testAllFlags(IS_METHOD | BRIDGE);
+ }
+ /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
+ public boolean isVarargs() {
+ return testAllFlags(VARARGS) && isInvocable();
+ }
+ /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
+ public boolean isSynthetic() {
+ return testAllFlags(SYNTHETIC);
+ }
+
+ static final String CONSTRUCTOR_NAME = ""; // the ever-popular
+
+ // modifiers exported by the JVM:
+ static final int RECOGNIZED_MODIFIERS = 0xFFFF;
+
+ // private flags, not part of RECOGNIZED_MODIFIERS:
+ static final int
+ IS_METHOD = MN_IS_METHOD, // method (not constructor)
+ IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
+ IS_FIELD = MN_IS_FIELD, // field
+ IS_TYPE = MN_IS_TYPE; // nested type
+ static final int // for MethodHandleNatives.getMembers
+ SEARCH_SUPERCLASSES = MN_SEARCH_SUPERCLASSES,
+ SEARCH_INTERFACES = MN_SEARCH_INTERFACES;
+
+ static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
+ static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
+ static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
+ static final int IS_FIELD_OR_METHOD = IS_METHOD | IS_FIELD;
+ static final int SEARCH_ALL_SUPERS = SEARCH_SUPERCLASSES | SEARCH_INTERFACES;
+
+ /** Utility method to query whether this member is a method or constructor. */
+ public boolean isInvocable() {
+ return testAnyFlags(IS_INVOCABLE);
+ }
+ /** Utility method to query whether this member is a method, constructor, or field. */
+ public boolean isFieldOrMethod() {
+ return testAnyFlags(IS_FIELD_OR_METHOD);
+ }
+ /** Query whether this member is a method. */
+ public boolean isMethod() {
+ return testAllFlags(IS_METHOD);
+ }
+ /** Query whether this member is a constructor. */
+ public boolean isConstructor() {
+ return testAllFlags(IS_CONSTRUCTOR);
+ }
+ /** Query whether this member is a field. */
+ public boolean isField() {
+ return testAllFlags(IS_FIELD);
+ }
+ /** Query whether this member is a type. */
+ public boolean isType() {
+ return testAllFlags(IS_TYPE);
+ }
+ /** Utility method to query whether this member is neither public, private, nor protected. */
+ public boolean isPackage() {
+ return !testAnyFlags(ALL_ACCESS);
+ }
+
+ /** Initialize a query. It is not resolved. */
+ private void init(Class> defClass, String name, Object type, int flags) {
+ // defining class is allowed to be null (for a naked name/type pair)
+ //name.toString(); // null check
+ //type.equals(type); // null check
+ // fill in fields:
+ this.clazz = defClass;
+ this.name = name;
+ this.type = type;
+ setFlags(flags);
+ assert(!isResolved());
+ }
+
+ private void expandFromVM() {
+ if (!isResolved()) return;
+ if (type instanceof Object[])
+ type = null; // don't saddle JVM w/ typeInfo
+ MethodHandleNatives.expand(this);
+ }
+
+ // Capturing information from the Core Reflection API:
+ private static int flagsMods(int flags, int mods) {
+ assert((flags & RECOGNIZED_MODIFIERS) == 0);
+ assert((mods & ~RECOGNIZED_MODIFIERS) == 0);
+ return flags | mods;
+ }
+ /** Create a name for the given reflected method. The resulting name will be in a resolved state. */
+ public MemberName(Method m) {
+ Object[] typeInfo = { m.getReturnType(), m.getParameterTypes() };
+ init(m.getDeclaringClass(), m.getName(), typeInfo, flagsMods(IS_METHOD, m.getModifiers()));
+ // fill in vmtarget, vmindex while we have m in hand:
+ MethodHandleNatives.init(this, m);
+ assert(isResolved());
+ }
+ /** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */
+ public MemberName(Constructor ctor) {
+ Object[] typeInfo = { void.class, ctor.getParameterTypes() };
+ init(ctor.getDeclaringClass(), CONSTRUCTOR_NAME, typeInfo, flagsMods(IS_CONSTRUCTOR, ctor.getModifiers()));
+ // fill in vmtarget, vmindex while we have ctor in hand:
+ MethodHandleNatives.init(this, ctor);
+ assert(isResolved());
+ }
+ /** Create a name for the given reflected field. The resulting name will be in a resolved state. */
+ public MemberName(Field fld) {
+ init(fld.getDeclaringClass(), fld.getName(), fld.getType(), flagsMods(IS_FIELD, fld.getModifiers()));
+ // fill in vmtarget, vmindex while we have fld in hand:
+ MethodHandleNatives.init(this, fld);
+ assert(isResolved());
+ }
+ /** Create a name for the given class. The resulting name will be in a resolved state. */
+ public MemberName(Class> type) {
+ init(type.getDeclaringClass(), type.getSimpleName(), type, flagsMods(IS_TYPE, type.getModifiers()));
+ vmindex = 0; // isResolved
+ assert(isResolved());
+ }
+
+ // bare-bones constructor; the JVM will fill it in
+ MemberName() { }
+
+ // locally useful cloner
+ @Override protected MemberName clone() {
+ try {
+ return (MemberName) super.clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
+ // %%% define equals/hashcode?
+
+ // Construction from symbolic parts, for queries:
+ /** Create a field or type name from the given components: Declaring class, name, type, modifiers.
+ * The declaring class may be supplied as null if this is to be a bare name and type.
+ * The resulting name will in an unresolved state.
+ */
+ public MemberName(Class> defClass, String name, Class> type, int modifiers) {
+ init(defClass, name, type, IS_FIELD | (modifiers & RECOGNIZED_MODIFIERS));
+ }
+ /** Create a field or type name from the given components: Declaring class, name, type.
+ * The declaring class may be supplied as null if this is to be a bare name and type.
+ * The modifier flags default to zero.
+ * The resulting name will in an unresolved state.
+ */
+ public MemberName(Class> defClass, String name, Class> type) {
+ this(defClass, name, type, 0);
+ }
+ /** Create a method or constructor name from the given components: Declaring class, name, type, modifiers.
+ * It will be a constructor if and only if the name is {@code "<init>"}.
+ * The declaring class may be supplied as null if this is to be a bare name and type.
+ * The resulting name will in an unresolved state.
+ */
+ public MemberName(Class> defClass, String name, MethodType type, int modifiers) {
+ int flagBit = (name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
+ init(defClass, name, type, flagBit | (modifiers & RECOGNIZED_MODIFIERS));
+ }
+ /** Create a method or constructor name from the given components: Declaring class, name, type, modifiers.
+ * It will be a constructor if and only if the name is {@code "<init>"}.
+ * The declaring class may be supplied as null if this is to be a bare name and type.
+ * The modifier flags default to zero.
+ * The resulting name will in an unresolved state.
+ */
+ public MemberName(Class> defClass, String name, MethodType type) {
+ this(defClass, name, type, 0);
+ }
+
+ /** Query whether this member name is resolved.
+ * A resolved member name is one for which the JVM has found
+ * a method, constructor, field, or type binding corresponding exactly to the name.
+ * (Document?)
+ */
+ public boolean isResolved() {
+ return (vmindex != VM_INDEX_UNINITIALIZED);
+ }
+
+ /** Query whether this member name is resolved to a non-static, non-final method.
+ */
+ public boolean hasReceiverTypeDispatch() {
+ return (isMethod() && getVMIndex() >= 0);
+ }
+
+ /** Produce a string form of this member name.
+ * For types, it is simply the type's own string (as reported by {@code toString}).
+ * For fields, it is {@code "DeclaringClass.name/type"}.
+ * For methods and constructors, it is {@code "DeclaringClass.name(ptype...)rtype"}.
+ * If the declaring class is null, the prefix {@code "DeclaringClass."} is omitted.
+ * If the member is unresolved, a prefix {@code "*."} is prepended.
+ */
+ @Override
+ public String toString() {
+ if (isType())
+ return type.toString(); // class java.lang.String
+ // else it is a field, method, or constructor
+ StringBuilder buf = new StringBuilder();
+ if (getDeclaringClass() != null) {
+ buf.append(getName(clazz));
+ buf.append('.');
+ }
+ String name = getName();
+ buf.append(name == null ? "*" : name);
+ Object type = getType();
+ if (!isInvocable()) {
+ buf.append('/');
+ buf.append(type == null ? "*" : getName(type));
+ } else {
+ buf.append(type == null ? "(*)*" : getName(type));
+ }
+ /*
+ buf.append('/');
+ // key: Public, private, pRotected, sTatic, Final, sYnchronized,
+ // transient/Varargs, native, (interface), abstract, sTrict, sYnthetic,
+ // (annotation), Enum, (unused)
+ final String FIELD_MOD_CHARS = "PprTF?vt????Y?E?";
+ final String METHOD_MOD_CHARS = "PprTFybVn?atY???";
+ String modChars = (isInvocable() ? METHOD_MOD_CHARS : FIELD_MOD_CHARS);
+ for (int i = 0; i < modChars.length(); i++) {
+ if ((flags & (1 << i)) != 0) {
+ char mc = modChars.charAt(i);
+ if (mc != '?')
+ buf.append(mc);
+ }
+ }
+ */
+ return buf.toString();
+ }
+ private static String getName(Object obj) {
+ if (obj instanceof Class>)
+ return ((Class>)obj).getName();
+ return String.valueOf(obj);
+ }
+
+ // Queries to the JVM:
+ /** Document? */
+ /*non-public*/ int getVMIndex() {
+ if (!isResolved())
+ throw newIllegalStateException("not resolved", this);
+ return vmindex;
+ }
+// /*non-public*/ Object getVMTarget() {
+// if (!isResolved())
+// throw newIllegalStateException("not resolved", this);
+// return vmtarget;
+// }
+
+ public IllegalAccessException makeAccessException(String message, Object from) {
+ message = message + ": "+ toString();
+ if (from != null) message += ", from " + from;
+ return new IllegalAccessException(message);
+ }
+ public ReflectiveOperationException makeAccessException(String message) {
+ message = message + ": "+ toString();
+ if (isResolved())
+ return new IllegalAccessException(message);
+ else if (isConstructor())
+ return new NoSuchMethodException(message);
+ else if (isMethod())
+ return new NoSuchMethodException(message);
+ else
+ return new NoSuchFieldException(message);
+ }
+
+ /** Actually making a query requires an access check. */
+ /*non-public*/ static Factory getFactory() {
+ return Factory.INSTANCE;
+ }
+ /** A factory type for resolving member names with the help of the VM.
+ * TBD: Define access-safe public constructors for this factory.
+ */
+ public static class Factory {
+ private Factory() { } // singleton pattern
+ static Factory INSTANCE = new Factory();
+
+ private static int ALLOWED_FLAGS = SEARCH_ALL_SUPERS | ALL_KINDS;
+
+ /// Queries
+ List getMembers(Class> defc,
+ String matchName, Object matchType,
+ int matchFlags, Class> lookupClass) {
+ matchFlags &= ALLOWED_FLAGS;
+ String matchSig = null;
+ if (matchType != null) {
+ matchSig = BytecodeDescriptor.unparse(matchType);
+ if (matchSig.startsWith("("))
+ matchFlags &= ~(ALL_KINDS & ~IS_INVOCABLE);
+ else
+ matchFlags &= ~(ALL_KINDS & ~IS_FIELD);
+ }
+ final int BUF_MAX = 0x2000;
+ int len1 = matchName == null ? 10 : matchType == null ? 4 : 1;
+ MemberName[] buf = newMemberBuffer(len1);
+ int totalCount = 0;
+ ArrayList bufs = null;
+ int bufCount = 0;
+ for (;;) {
+ bufCount = MethodHandleNatives.getMembers(defc,
+ matchName, matchSig, matchFlags,
+ lookupClass,
+ totalCount, buf);
+ if (bufCount <= buf.length) {
+ if (bufCount < 0) bufCount = 0;
+ totalCount += bufCount;
+ break;
+ }
+ // JVM returned to us with an intentional overflow!
+ totalCount += buf.length;
+ int excess = bufCount - buf.length;
+ if (bufs == null) bufs = new ArrayList(1);
+ bufs.add(buf);
+ int len2 = buf.length;
+ len2 = Math.max(len2, excess);
+ len2 = Math.max(len2, totalCount / 4);
+ buf = newMemberBuffer(Math.min(BUF_MAX, len2));
+ }
+ ArrayList result = new ArrayList(totalCount);
+ if (bufs != null) {
+ for (MemberName[] buf0 : bufs) {
+ Collections.addAll(result, buf0);
+ }
+ }
+ result.addAll(Arrays.asList(buf).subList(0, bufCount));
+ // Signature matching is not the same as type matching, since
+ // one signature might correspond to several types.
+ // So if matchType is a Class or MethodType, refilter the results.
+ if (matchType != null && matchType != matchSig) {
+ for (Iterator it = result.iterator(); it.hasNext();) {
+ MemberName m = it.next();
+ if (!matchType.equals(m.getType()))
+ it.remove();
+ }
+ }
+ return result;
+ }
+ boolean resolveInPlace(MemberName m, boolean searchSupers, Class> lookupClass) {
+ if (m.name == null || m.type == null) { // find unique non-overloaded name
+ Class> defc = m.getDeclaringClass();
+ List choices = null;
+ if (m.isMethod())
+ choices = getMethods(defc, searchSupers, m.name, (MethodType) m.type, lookupClass);
+ else if (m.isConstructor())
+ choices = getConstructors(defc, lookupClass);
+ else if (m.isField())
+ choices = getFields(defc, searchSupers, m.name, (Class>) m.type, lookupClass);
+ //System.out.println("resolving "+m+" to "+choices);
+ if (choices == null || choices.size() != 1)
+ return false;
+ if (m.name == null) m.name = choices.get(0).name;
+ if (m.type == null) m.type = choices.get(0).type;
+ }
+ MethodHandleNatives.resolve(m, lookupClass);
+ if (m.isResolved()) return true;
+ int matchFlags = m.flags | (searchSupers ? SEARCH_ALL_SUPERS : 0);
+ String matchSig = m.getSignature();
+ MemberName[] buf = { m };
+ int n = MethodHandleNatives.getMembers(m.getDeclaringClass(),
+ m.getName(), matchSig, matchFlags, lookupClass, 0, buf);
+ if (n != 1) return false;
+ return m.isResolved();
+ }
+ /** Produce a resolved version of the given member.
+ * Super types are searched (for inherited members) if {@code searchSupers} is true.
+ * Access checking is performed on behalf of the given {@code lookupClass}.
+ * If lookup fails or access is not permitted, null is returned.
+ * Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
+ */
+ public MemberName resolveOrNull(MemberName m, boolean searchSupers, Class> lookupClass) {
+ MemberName result = m.clone();
+ if (resolveInPlace(result, searchSupers, lookupClass))
+ return result;
+ return null;
+ }
+ /** Produce a resolved version of the given member.
+ * Super types are searched (for inherited members) if {@code searchSupers} is true.
+ * Access checking is performed on behalf of the given {@code lookupClass}.
+ * If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown.
+ * Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
+ */
+ public
+
+ MemberName resolveOrFail(MemberName m, boolean searchSupers, Class> lookupClass,
+ Class nsmClass)
+ throws IllegalAccessException, NoSuchMemberException {
+ MemberName result = resolveOrNull(m, searchSupers, lookupClass);
+ if (result != null)
+ return result;
+ ReflectiveOperationException ex = m.makeAccessException("no access");
+ if (ex instanceof IllegalAccessException) throw (IllegalAccessException) ex;
+ throw nsmClass.cast(ex);
+ }
+ /** Return a list of all methods defined by the given class.
+ * Super types are searched (for inherited members) if {@code searchSupers} is true.
+ * Access checking is performed on behalf of the given {@code lookupClass}.
+ * Inaccessible members are not added to the last.
+ */
+ public List getMethods(Class> defc, boolean searchSupers,
+ Class> lookupClass) {
+ return getMethods(defc, searchSupers, null, null, lookupClass);
+ }
+ /** Return a list of matching methods defined by the given class.
+ * Super types are searched (for inherited members) if {@code searchSupers} is true.
+ * Returned methods will match the name (if not null) and the type (if not null).
+ * Access checking is performed on behalf of the given {@code lookupClass}.
+ * Inaccessible members are not added to the last.
+ */
+ public List getMethods(Class> defc, boolean searchSupers,
+ String name, MethodType type, Class> lookupClass) {
+ int matchFlags = IS_METHOD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
+ return getMembers(defc, name, type, matchFlags, lookupClass);
+ }
+ /** Return a list of all constructors defined by the given class.
+ * Access checking is performed on behalf of the given {@code lookupClass}.
+ * Inaccessible members are not added to the last.
+ */
+ public List getConstructors(Class> defc, Class> lookupClass) {
+ return getMembers(defc, null, null, IS_CONSTRUCTOR, lookupClass);
+ }
+ /** Return a list of all fields defined by the given class.
+ * Super types are searched (for inherited members) if {@code searchSupers} is true.
+ * Access checking is performed on behalf of the given {@code lookupClass}.
+ * Inaccessible members are not added to the last.
+ */
+ public List getFields(Class> defc, boolean searchSupers,
+ Class> lookupClass) {
+ return getFields(defc, searchSupers, null, null, lookupClass);
+ }
+ /** Return a list of all fields defined by the given class.
+ * Super types are searched (for inherited members) if {@code searchSupers} is true.
+ * Returned fields will match the name (if not null) and the type (if not null).
+ * Access checking is performed on behalf of the given {@code lookupClass}.
+ * Inaccessible members are not added to the last.
+ */
+ public List getFields(Class> defc, boolean searchSupers,
+ String name, Class> type, Class> lookupClass) {
+ int matchFlags = IS_FIELD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
+ return getMembers(defc, name, type, matchFlags, lookupClass);
+ }
+ /** Return a list of all nested types defined by the given class.
+ * Super types are searched (for inherited members) if {@code searchSupers} is true.
+ * Access checking is performed on behalf of the given {@code lookupClass}.
+ * Inaccessible members are not added to the last.
+ */
+ public List getNestedTypes(Class> defc, boolean searchSupers,
+ Class> lookupClass) {
+ int matchFlags = IS_TYPE | (searchSupers ? SEARCH_ALL_SUPERS : 0);
+ return getMembers(defc, null, null, matchFlags, lookupClass);
+ }
+ private static MemberName[] newMemberBuffer(int length) {
+ MemberName[] buf = new MemberName[length];
+ // fill the buffer with dummy structs for the JVM to fill in
+ for (int i = 0; i < length; i++)
+ buf[i] = new MemberName();
+ return buf;
+ }
+ }
+
+// static {
+// System.out.println("Hello world! My methods are:");
+// System.out.println(Factory.INSTANCE.getMethods(MemberName.class, true, null));
+// }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MethodHandle.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,1028 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A method handle is a typed, directly executable reference to an underlying method,
+ * constructor, field, or similar low-level operation, with optional
+ * transformations of arguments or return values.
+ * These transformations are quite general, and include such patterns as
+ * {@linkplain #asType conversion},
+ * {@linkplain #bindTo insertion},
+ * {@linkplain java.lang.invoke.MethodHandles#dropArguments deletion},
+ * and {@linkplain java.lang.invoke.MethodHandles#filterArguments substitution}.
+ *
+ * Method handle contents
+ * Method handles are dynamically and strongly typed according to type descriptor.
+ * They are not distinguished by the name or defining class of their underlying methods.
+ * A method handle must be invoked using type descriptor which matches
+ * the method handle's own {@linkplain #type method type}.
+ *
+ * Every method handle reports its type via the {@link #type type} accessor.
+ * This type descriptor is a {@link java.lang.invoke.MethodType MethodType} object,
+ * whose structure is a series of classes, one of which is
+ * the return type of the method (or {@code void.class} if none).
+ *
+ * A method handle's type controls the types of invocations it accepts,
+ * and the kinds of transformations that apply to it.
+ *
+ * A method handle contains a pair of special invoker methods
+ * called {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.
+ * Both invoker methods provide direct access to the method handle's
+ * underlying method, constructor, field, or other operation,
+ * as modified by transformations of arguments and return values.
+ * Both invokers accept calls which exactly match the method handle's own type.
+ * The {@code invokeGeneric} invoker also accepts a range of other call types.
+ *
+ * Method handles are immutable and have no visible state.
+ * Of course, they can be bound to underlying methods or data which exhibit state.
+ * With respect to the Java Memory Model, any method handle will behave
+ * as if all of its (internal) fields are final variables. This means that any method
+ * handle made visible to the application will always be fully formed.
+ * This is true even if the method handle is published through a shared
+ * variable in a data race.
+ *
+ * Method handles cannot be subclassed by the user.
+ * Implementations may (or may not) create internal subclasses of {@code MethodHandle}
+ * which may be visible via the {@link java.lang.Object#getClass Object.getClass}
+ * operation. The programmer should not draw conclusions about a method handle
+ * from its specific class, as the method handle class hierarchy (if any)
+ * may change from time to time or across implementations from different vendors.
+ *
+ *
Method handle compilation
+ * A Java method call expression naming {@code invokeExact} or {@code invokeGeneric}
+ * can invoke a method handle from Java source code.
+ * From the viewpoint of source code, these methods can take any arguments
+ * and their result can be cast to any return type.
+ * Formally this is accomplished by giving the invoker methods
+ * {@code Object} return types and variable-arity {@code Object} arguments,
+ * but they have an additional quality called signature polymorphism
+ * which connects this freedom of invocation directly to the JVM execution stack.
+ *
+ * As is usual with virtual methods, source-level calls to {@code invokeExact}
+ * and {@code invokeGeneric} compile to an {@code invokevirtual} instruction.
+ * More unusually, the compiler must record the actual argument types,
+ * and may not perform method invocation conversions on the arguments.
+ * Instead, it must push them on the stack according to their own unconverted types.
+ * The method handle object itself is pushed on the stack before the arguments.
+ * The compiler then calls the method handle with a type descriptor which
+ * describes the argument and return types.
+ *
+ * To issue a complete type descriptor, the compiler must also determine
+ * the return type. This is based on a cast on the method invocation expression,
+ * if there is one, or else {@code Object} if the invocation is an expression
+ * or else {@code void} if the invocation is a statement.
+ * The cast may be to a primitive type (but not {@code void}).
+ *
+ * As a corner case, an uncasted {@code null} argument is given
+ * a type descriptor of {@code java.lang.Void}.
+ * The ambiguity with the type {@code Void} is harmless, since there are no references of type
+ * {@code Void} except the null reference.
+ *
+ *
Method handle invocation
+ * The first time a {@code invokevirtual} instruction is executed
+ * it is linked, by symbolically resolving the names in the instruction
+ * and verifying that the method call is statically legal.
+ * This is true of calls to {@code invokeExact} and {@code invokeGeneric}.
+ * In this case, the type descriptor emitted by the compiler is checked for
+ * correct syntax and names it contains are resolved.
+ * Thus, an {@code invokevirtual} instruction which invokes
+ * a method handle will always link, as long
+ * as the type descriptor is syntactically well-formed
+ * and the types exist.
+ *
+ * When the {@code invokevirtual} is executed after linking,
+ * the receiving method handle's type is first checked by the JVM
+ * to ensure that it matches the descriptor.
+ * If the type match fails, it means that the method which the
+ * caller is invoking is not present on the individual
+ * method handle being invoked.
+ *
+ * In the case of {@code invokeExact}, the type descriptor of the invocation
+ * (after resolving symbolic type names) must exactly match the method type
+ * of the receiving method handle.
+ * In the case of {@code invokeGeneric}, the resolved type descriptor
+ * must be a valid argument to the receiver's {@link #asType asType} method.
+ * Thus, {@code invokeGeneric} is more permissive than {@code invokeExact}.
+ *
+ * After type matching, a call to {@code invokeExact} directly
+ * and immediately invoke the method handle's underlying method
+ * (or other behavior, as the case may be).
+ *
+ * A call to {@code invokeGeneric} works the same as a call to
+ * {@code invokeExact}, if the type descriptor specified by the caller
+ * exactly matches the method handle's own type.
+ * If there is a type mismatch, {@code invokeGeneric} attempts
+ * to adjust the type of the receiving method handle,
+ * as if by a call to {@link #asType asType},
+ * to obtain an exactly invokable method handle {@code M2}.
+ * This allows a more powerful negotiation of method type
+ * between caller and callee.
+ *
+ * (Note: The adjusted method handle {@code M2} is not directly observable,
+ * and implementations are therefore not required to materialize it.)
+ *
+ *
Invocation checking
+ * In typical programs, method handle type matching will usually succeed.
+ * But if a match fails, the JVM will throw a {@link WrongMethodTypeException},
+ * either directly (in the case of {@code invokeExact}) or indirectly as if
+ * by a failed call to {@code asType} (in the case of {@code invokeGeneric}).
+ *
+ * Thus, a method type mismatch which might show up as a linkage error
+ * in a statically typed program can show up as
+ * a dynamic {@code WrongMethodTypeException}
+ * in a program which uses method handles.
+ *
+ * Because method types contain "live" {@code Class} objects,
+ * method type matching takes into account both types names and class loaders.
+ * Thus, even if a method handle {@code M} is created in one
+ * class loader {@code L1} and used in another {@code L2},
+ * method handle calls are type-safe, because the caller's type
+ * descriptor, as resolved in {@code L2},
+ * is matched against the original callee method's type descriptor,
+ * as resolved in {@code L1}.
+ * The resolution in {@code L1} happens when {@code M} is created
+ * and its type is assigned, while the resolution in {@code L2} happens
+ * when the {@code invokevirtual} instruction is linked.
+ *
+ * Apart from the checking of type descriptors,
+ * a method handle's capability to call its underlying method is unrestricted.
+ * If a method handle is formed on a non-public method by a class
+ * that has access to that method, the resulting handle can be used
+ * in any place by any caller who receives a reference to it.
+ *
+ * Unlike with the Core Reflection API, where access is checked every time
+ * a reflective method is invoked,
+ * method handle access checking is performed
+ * when the method handle is created .
+ * In the case of {@code ldc} (see below), access checking is performed as part of linking
+ * the constant pool entry underlying the constant method handle.
+ *
+ * Thus, handles to non-public methods, or to methods in non-public classes,
+ * should generally be kept secret.
+ * They should not be passed to untrusted code unless their use from
+ * the untrusted code would be harmless.
+ *
+ *
Method handle creation
+ * Java code can create a method handle that directly accesses
+ * any method, constructor, or field that is accessible to that code.
+ * This is done via a reflective, capability-based API called
+ * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
+ * For example, a static method handle can be obtained
+ * from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
+ * There are also conversion methods from Core Reflection API objects,
+ * such as {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ *
+ * Like classes and strings, method handles that correspond to accessible
+ * fields, methods, and constructors can also be represented directly
+ * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
+ * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
+ * refers directly to an associated {@code CONSTANT_Methodref},
+ * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
+ * constant pool entry.
+ * (For more details on method handle constants,
+ * see the package summary .)
+ *
+ * Method handles produced by lookups or constant loads from methods or
+ * constructors with the variable arity modifier bit ({@code 0x0080})
+ * have a corresponding variable arity, as if they were defined with
+ * the help of {@link #asVarargsCollector asVarargsCollector}.
+ *
+ * A method reference may refer either to a static or non-static method.
+ * In the non-static case, the method handle type includes an explicit
+ * receiver argument, prepended before any other arguments.
+ * In the method handle's type, the initial receiver argument is typed
+ * according to the class under which the method was initially requested.
+ * (E.g., if a non-static method handle is obtained via {@code ldc},
+ * the type of the receiver is the class named in the constant pool entry.)
+ *
+ * When a method handle to a virtual method is invoked, the method is
+ * always looked up in the receiver (that is, the first argument).
+ *
+ * A non-virtual method handle to a specific virtual method implementation
+ * can also be created. These do not perform virtual lookup based on
+ * receiver type. Such a method handle simulates the effect of
+ * an {@code invokespecial} instruction to the same method.
+ *
+ *
Usage examples
+ * Here are some examples of usage:
+ *
+Object x, y; String s; int i;
+MethodType mt; MethodHandle mh;
+MethodHandles.Lookup lookup = MethodHandles.lookup();
+// mt is (char,char)String
+mt = MethodType.methodType(String.class, char.class, char.class);
+mh = lookup.findVirtual(String.class, "replace", mt);
+s = (String) mh.invokeExact("daddy",'d','n');
+// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
+assert(s.equals("nanny"));
+// weakly typed invocation (using MHs.invoke)
+s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
+assert(s.equals("savvy"));
+// mt is (Object[])List
+mt = MethodType.methodType(java.util.List.class, Object[].class);
+mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
+assert(mh.isVarargsCollector());
+x = mh.invokeGeneric("one", "two");
+// invokeGeneric(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
+assert(x.equals(java.util.Arrays.asList("one","two")));
+// mt is (Object,Object,Object)Object
+mt = MethodType.genericMethodType(3);
+mh = mh.asType(mt);
+x = mh.invokeExact((Object)1, (Object)2, (Object)3);
+// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+assert(x.equals(java.util.Arrays.asList(1,2,3)));
+// mt is int()
+mt = MethodType.methodType(int.class);
+mh = lookup.findVirtual(java.util.List.class, "size", mt);
+i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
+// invokeExact(Ljava/util/List;)I
+assert(i == 3);
+mt = MethodType.methodType(void.class, String.class);
+mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
+mh.invokeExact(System.out, "Hello, world.");
+// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
+ *
+ * Each of the above calls to {@code invokeExact} or {@code invokeGeneric}
+ * generates a single invokevirtual instruction with
+ * the type descriptor indicated in the following comment.
+ *
+ * Exceptions
+ * The methods {@code invokeExact} and {@code invokeGeneric} are declared
+ * to throw {@link java.lang.Throwable Throwable},
+ * which is to say that there is no static restriction on what a method handle
+ * can throw. Since the JVM does not distinguish between checked
+ * and unchecked exceptions (other than by their class, of course),
+ * there is no particular effect on bytecode shape from ascribing
+ * checked exceptions to method handle invocations. But in Java source
+ * code, methods which perform method handle calls must either explicitly
+ * throw {@code java.lang.Throwable Throwable}, or else must catch all
+ * throwables locally, rethrowing only those which are legal in the context,
+ * and wrapping ones which are illegal.
+ *
+ * Signature polymorphism
+ * The unusual compilation and linkage behavior of
+ * {@code invokeExact} and {@code invokeGeneric}
+ * is referenced by the term signature polymorphism .
+ * A signature polymorphic method is one which can operate with
+ * any of a wide range of call signatures and return types.
+ * In order to make this work, both the Java compiler and the JVM must
+ * give special treatment to signature polymorphic methods.
+ *
+ * In source code, a call to a signature polymorphic method will
+ * compile, regardless of the requested type descriptor.
+ * As usual, the Java compiler emits an {@code invokevirtual}
+ * instruction with the given type descriptor against the named method.
+ * The unusual part is that the type descriptor is derived from
+ * the actual argument and return types, not from the method declaration.
+ *
+ * When the JVM processes bytecode containing signature polymorphic calls,
+ * it will successfully link any such call, regardless of its type descriptor.
+ * (In order to retain type safety, the JVM will guard such calls with suitable
+ * dynamic type checks, as described elsewhere.)
+ *
+ * Bytecode generators, including the compiler back end, are required to emit
+ * untransformed type descriptors for these methods.
+ * Tools which determine symbolic linkage are required to accept such
+ * untransformed descriptors, without reporting linkage errors.
+ *
+ * For the sake of tools (but not as a programming API), the signature polymorphic
+ * methods are marked with a private yet standard annotation,
+ * {@code @java.lang.invoke.MethodHandle.PolymorphicSignature}.
+ * The annotation's retention is {@code RUNTIME}, so that all tools can see it.
+ *
+ *
Formal rules for processing signature polymorphic methods
+ *
+ * The following methods (and no others) are signature polymorphic:
+ *
+ * {@link java.lang.invoke.MethodHandle#invokeExact MethodHandle.invokeExact}
+ * {@link java.lang.invoke.MethodHandle#invokeGeneric MethodHandle.invokeGeneric}
+ *
+ *
+ * A signature polymorphic method will be declared with the following properties:
+ *
+ * It must be native.
+ * It must take a single varargs parameter of the form {@code Object...}.
+ * It must produce a return value of type {@code Object}.
+ * It must be contained within the {@code java.lang.invoke} package.
+ *
+ * Because of these requirements, a signature polymorphic method is able to accept
+ * any number and type of actual arguments, and can, with a cast, produce a value of any type.
+ * However, the JVM will treat these declaration features as a documentation convention,
+ * rather than a description of the actual structure of the methods as executed.
+ *
+ * When a call to a signature polymorphic method is compiled, the associated linkage information for
+ * its arguments is not array of {@code Object} (as for other similar varargs methods)
+ * but rather the erasure of the static types of all the arguments.
+ *
+ * In an argument position of a method invocation on a signature polymorphic method,
+ * a null literal has type {@code java.lang.Void}, unless cast to a reference type.
+ * (Note: This typing rule allows the null type to have its own encoding in linkage information
+ * distinct from other types.
+ *
+ * The linkage information for the return type is derived from a context-dependent target typing convention.
+ * The return type for a signature polymorphic method invocation is determined as follows:
+ *
+ * If the method invocation expression is an expression statement, the method is {@code void}.
+ * Otherwise, if the method invocation expression is the immediate operand of a cast,
+ * the return type is the erasure of the cast type.
+ * Otherwise, the return type is the method's nominal return type, {@code Object}.
+ *
+ * (Programmers are encouraged to use explicit casts unless it is clear that a signature polymorphic
+ * call will be used as a plain {@code Object} expression.)
+ *
+ * The linkage information for argument and return types is stored in the descriptor for the
+ * compiled (bytecode) call site. As for any invocation instruction, the arguments and return value
+ * will be passed directly on the JVM stack, in accordance with the descriptor,
+ * and without implicit boxing or unboxing.
+ *
+ *
Interoperation between method handles and the Core Reflection API
+ * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup Lookup} API,
+ * any class member represented by a Core Reflection API object
+ * can be converted to a behaviorally equivalent method handle.
+ * For example, a reflective {@link java.lang.reflect.Method Method} can
+ * be converted to a method handle using
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * The resulting method handles generally provide more direct and efficient
+ * access to the underlying class members.
+ *
+ * As a special case,
+ * when the Core Reflection API is used to view the signature polymorphic
+ * methods {@code invokeExact} or {@code invokeGeneric} in this class,
+ * they appear as single, non-polymorphic native methods.
+ * Calls to these native methods do not result in method handle invocations.
+ * Since {@code invokevirtual} instructions can natively
+ * invoke method handles under any type descriptor, this reflective view conflicts
+ * with the normal presentation via bytecodes.
+ * Thus, these two native methods, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * are placeholders only.
+ * If invoked via {@link java.lang.reflect.Method#invoke Method.invoke},
+ * they will throw {@code UnsupportedOperationException}.
+ *
+ * In order to obtain an invoker method for a particular type descriptor,
+ * use {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker},
+ * or {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}.
+ * The {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
+ * API is also able to return a method handle
+ * to call {@code invokeExact} or {@code invokeGeneric},
+ * for any specified type descriptor .
+ *
+ *
Interoperation between method handles and Java generics
+ * A method handle can be obtained on a method, constructor, or field
+ * which is declared with Java generic types.
+ * As with the Core Reflection API, the type of the method handle
+ * will constructed from the erasure of the source-level type.
+ * When a method handle is invoked, the types of its arguments
+ * or the return value cast type may be generic types or type instances.
+ * If this occurs, the compiler will replace those
+ * types by their erasures when when it constructs the type descriptor
+ * for the {@code invokevirtual} instruction.
+ *
+ * Method handles do not represent
+ * their function-like types in terms of Java parameterized (generic) types,
+ * because there are three mismatches between function-like types and parameterized
+ * Java types.
+ *
+ * Method types range over all possible arities,
+ * from no arguments to up to 255 of arguments (a limit imposed by the JVM).
+ * Generics are not variadic, and so cannot represent this.
+ * Method types can specify arguments of primitive types,
+ * which Java generic types cannot range over.
+ * Higher order functions over method handles (combinators) are
+ * often generic across a wide range of function types, including
+ * those of multiple arities. It is impossible to represent such
+ * genericity with a Java type parameter.
+ *
+ *
+ * @see MethodType
+ * @see MethodHandles
+ * @author John Rose, JSR 292 EG
+ */
+public abstract class MethodHandle {
+ // { JVM internals:
+
+ private byte vmentry; // adapter stub or method entry point
+ //private int vmslots; // optionally, hoist type.form.vmslots
+ /*non-public*/ Object vmtarget; // VM-specific, class-specific target value
+
+ // TO DO: vmtarget should be invisible to Java, since the JVM puts internal
+ // managed pointers into it. Making it visible exposes it to debuggers,
+ // which can cause errors when they treat the pointer as an Object.
+
+ // These two dummy fields are present to force 'I' and 'J' signatures
+ // into this class's constant pool, so they can be transferred
+ // to vmentry when this class is loaded.
+ static final int INT_FIELD = 0;
+ static final long LONG_FIELD = 0;
+
+ // vmentry (a void* field) is used *only* by the JVM.
+ // The JVM adjusts its type to int or long depending on system wordsize.
+ // Since it is statically typed as neither int nor long, it is impossible
+ // to use this field from Java bytecode. (Please don't try to, either.)
+
+ // The vmentry is an assembly-language stub which is jumped to
+ // immediately after the method type is verified.
+ // For a direct MH, this stub loads the vmtarget's entry point
+ // and jumps to it.
+
+ // } End of JVM internals.
+
+ static { MethodHandleImpl.initStatics(); }
+
+ // interface MethodHandle
+ // { MethodType type(); public R invokeExact(A...) throws X; }
+
+ /**
+ * Internal marker interface which distinguishes (to the Java compiler)
+ * those methods which are signature polymorphic .
+ */
+ @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
+ @interface PolymorphicSignature { }
+
+ private MethodType type;
+
+ /**
+ * Reports the type of this method handle.
+ * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
+ * @return the method handle type
+ */
+ public MethodType type() {
+ return type;
+ }
+
+ /**
+ * Package-private constructor for the method handle implementation hierarchy.
+ * Method handle inheritance will be contained completely within
+ * the {@code java.lang.invoke} package.
+ */
+ // @param type type (permanently assigned) of the new method handle
+ /*non-public*/ MethodHandle(MethodType type) {
+ type.getClass(); // elicit NPE
+ this.type = type;
+ }
+
+ /**
+ * Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
+ * The type descriptor at the call site of {@code invokeExact} must
+ * exactly match this method handle's {@link #type type}.
+ * No conversions are allowed on arguments or return values.
+ *
+ * When this method is observed via the Core Reflection API,
+ * it will appear as a single native method, taking an object array and returning an object.
+ * If this native method is invoked directly via
+ * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
+ * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
+ * it will throw an {@code UnsupportedOperationException}.
+ * @throws WrongMethodTypeException if the target's type is not identical with the caller's type descriptor
+ * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
+ */
+ public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
+
+ /**
+ * Invokes the method handle, allowing any caller type descriptor,
+ * and optionally performing conversions on arguments and return values.
+ *
+ * If the call site type descriptor exactly matches this method handle's {@link #type type},
+ * the call proceeds as if by {@link #invokeExact invokeExact}.
+ *
+ * Otherwise, the call proceeds as if this method handle were first
+ * adjusted by calling {@link #asType asType} to adjust this method handle
+ * to the required type, and then the call proceeds as if by
+ * {@link #invokeExact invokeExact} on the adjusted method handle.
+ *
+ * There is no guarantee that the {@code asType} call is actually made.
+ * If the JVM can predict the results of making the call, it may perform
+ * adaptations directly on the caller's arguments,
+ * and call the target method handle according to its own exact type.
+ *
+ * The type descriptor at the call site of {@code invokeGeneric} must
+ * be a valid argument to the receivers {@code asType} method.
+ * In particular, the caller must specify the same argument arity
+ * as the callee's type,
+ * if the callee is not a {@linkplain #asVarargsCollector variable arity collector}.
+ *
+ * When this method is observed via the Core Reflection API,
+ * it will appear as a single native method, taking an object array and returning an object.
+ * If this native method is invoked directly via
+ * {@link java.lang.reflect.Method#invoke Method.invoke}, via JNI,
+ * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
+ * it will throw an {@code UnsupportedOperationException}.
+ * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's type descriptor
+ * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
+ * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
+ */
+ public final native @PolymorphicSignature Object invokeGeneric(Object... args) throws Throwable;
+
+ /**
+ * Performs a varargs invocation, passing the arguments in the given array
+ * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
+ * which mentions only the type {@code Object}, and whose arity is the length
+ * of the argument array.
+ *
+ * Specifically, execution proceeds as if by the following steps,
+ * although the methods are not guaranteed to be called if the JVM
+ * can predict their effects.
+ *
+ * Determine the length of the argument array as {@code N}.
+ * For a null reference, {@code N=0}.
+ * Determine the generic type {@code TN} of {@code N} arguments as
+ * as {@code TN=MethodType.genericMethodType(N)}.
+ * Force the original target method handle {@code MH0} to the
+ * required type, as {@code MH1 = MH0.asType(TN)}.
+ * Spread the array into {@code N} separate arguments {@code A0, ...}.
+ * Invoke the type-adjusted method handle on the unpacked arguments:
+ * MH1.invokeExact(A0, ...).
+ * Take the return value as an {@code Object} reference.
+ *
+ *
+ * Because of the action of the {@code asType} step, the following argument
+ * conversions are applied as necessary:
+ *
+ * reference casting
+ * unboxing
+ * widening primitive conversions
+ *
+ *
+ * The result returned by the call is boxed if it is a primitive,
+ * or forced to null if the return type is void.
+ *
+ * This call is equivalent to the following code:
+ *
+ * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
+ * Object result = invoker.invokeExact(this, arguments);
+ *
+ *
+ * Unlike the signature polymorphic methods {@code invokeExact} and {@code invokeGeneric},
+ * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
+ * It can therefore be used as a bridge between native or reflective code and method handles.
+ *
+ * @param arguments the arguments to pass to the target
+ * @return the result returned by the target
+ * @throws ClassCastException if an argument cannot be converted by reference casting
+ * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
+ * @throws Throwable anything thrown by the target method invocation
+ * @see MethodHandles#spreadInvoker
+ */
+ public Object invokeWithArguments(Object... arguments) throws Throwable {
+ int argc = arguments == null ? 0 : arguments.length;
+ MethodType type = type();
+ if (type.parameterCount() != argc) {
+ // simulate invokeGeneric
+ return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
+ }
+ if (argc <= 10) {
+ MethodHandle invoker = type.invokers().genericInvoker();
+ switch (argc) {
+ case 0: return invoker.invokeExact(this);
+ case 1: return invoker.invokeExact(this,
+ arguments[0]);
+ case 2: return invoker.invokeExact(this,
+ arguments[0], arguments[1]);
+ case 3: return invoker.invokeExact(this,
+ arguments[0], arguments[1], arguments[2]);
+ case 4: return invoker.invokeExact(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3]);
+ case 5: return invoker.invokeExact(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4]);
+ case 6: return invoker.invokeExact(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5]);
+ case 7: return invoker.invokeExact(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5],
+ arguments[6]);
+ case 8: return invoker.invokeExact(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5],
+ arguments[6], arguments[7]);
+ case 9: return invoker.invokeExact(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5],
+ arguments[6], arguments[7], arguments[8]);
+ case 10: return invoker.invokeExact(this,
+ arguments[0], arguments[1], arguments[2],
+ arguments[3], arguments[4], arguments[5],
+ arguments[6], arguments[7], arguments[8],
+ arguments[9]);
+ }
+ }
+
+ // more than ten arguments get boxed in a varargs list:
+ MethodHandle invoker = type.invokers().spreadInvoker(0);
+ return invoker.invokeExact(this, arguments);
+ }
+
+ /**
+ * Performs a varargs invocation, passing the arguments in the given array
+ * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
+ * which mentions only the type {@code Object}, and whose arity is the length
+ * of the argument array.
+ *
+ * This method is also equivalent to the following code:
+ *
+ * {@link #invokeWithArguments(Object...) invokeWithArguments}(arguments.toArray())
+ *
+ *
+ * @param arguments the arguments to pass to the target
+ * @return the result returned by the target
+ * @throws ClassCastException if an argument cannot be converted by reference casting
+ * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
+ * @throws Throwable anything thrown by the target method invocation
+ */
+ public Object invokeWithArguments(java.util.List> arguments) throws Throwable {
+ return invokeWithArguments(arguments.toArray());
+ }
+
+ /**
+ * Produces an adapter method handle which adapts the type of the
+ * current method handle to a new type.
+ * The resulting method handle is guaranteed to report a type
+ * which is equal to the desired new type.
+ *
+ * If the original type and new type are equal, returns {@code this}.
+ *
+ * This method provides the crucial behavioral difference between
+ * {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}. The two methods
+ * perform the same steps when the caller's type descriptor is identical
+ * with the callee's, but when the types differ, {@link #invokeGeneric invokeGeneric}
+ * also calls {@code asType} (or some internal equivalent) in order
+ * to match up the caller's and callee's types.
+ *
+ * This method is equivalent to {@link MethodHandles#convertArguments convertArguments},
+ * except for variable arity method handles produced by {@link #asVarargsCollector asVarargsCollector}.
+ *
+ * @param newType the expected type of the new method handle
+ * @return a method handle which delegates to {@code this} after performing
+ * any necessary argument conversions, and arranges for any
+ * necessary return value conversions
+ * @throws WrongMethodTypeException if the conversion cannot be made
+ * @see MethodHandles#convertArguments
+ */
+ public MethodHandle asType(MethodType newType) {
+ return MethodHandles.convertArguments(this, newType);
+ }
+
+ /**
+ * Makes an adapter which accepts a trailing array argument
+ * and spreads its elements as positional arguments.
+ * The new method handle adapts, as its target ,
+ * the current method handle. The type of the adapter will be
+ * the same as the type of the target, except that the final
+ * {@code arrayLength} parameters of the target's type are replaced
+ * by a single array parameter of type {@code arrayType}.
+ *
+ * If the array element type differs from any of the corresponding
+ * argument types on the original target,
+ * the original target is adapted to take the array elements directly,
+ * as if by a call to {@link #asType asType}.
+ *
+ * When called, the adapter replaces a trailing array argument
+ * by the array's elements, each as its own argument to the target.
+ * (The order of the arguments is preserved.)
+ * They are converted pairwise by casting and/or unboxing
+ * to the types of the trailing parameters of the target.
+ * Finally the target is called.
+ * What the target eventually returns is returned unchanged by the adapter.
+ *
+ * Before calling the target, the adapter verifies that the array
+ * contains exactly enough elements to provide a correct argument count
+ * to the target method handle.
+ * (The array may also be null when zero elements are required.)
+ * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
+ * @param arrayLength the number of arguments to spread from an incoming array argument
+ * @return a new method handle which spreads its final array argument,
+ * before calling the original method handle
+ * @throws IllegalArgumentException if {@code arrayType} is not an array type
+ * @throws IllegalArgumentException if target does not have at least
+ * {@code arrayLength} parameter types
+ * @throws WrongMethodTypeException if the implied {@code asType} call fails
+ * @see #asCollector
+ */
+ public MethodHandle asSpreader(Class> arrayType, int arrayLength) {
+ Class> arrayElement = arrayType.getComponentType();
+ if (arrayElement == null) throw newIllegalArgumentException("not an array type");
+ MethodType oldType = type();
+ int nargs = oldType.parameterCount();
+ if (nargs < arrayLength) throw newIllegalArgumentException("bad spread array length");
+ int keepPosArgs = nargs - arrayLength;
+ MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
+ newType = newType.insertParameterTypes(keepPosArgs, arrayType);
+ return MethodHandles.spreadArguments(this, newType);
+ }
+
+ /**
+ * Makes an adapter which accepts a given number of trailing
+ * positional arguments and collects them into an array argument.
+ * The new method handle adapts, as its target ,
+ * the current method handle. The type of the adapter will be
+ * the same as the type of the target, except that a single trailing
+ * parameter (usually of type {@code arrayType}) is replaced by
+ * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
+ *
+ * If the array type differs from the final argument type on the original target,
+ * the original target is adapted to take the array type directly,
+ * as if by a call to {@link #asType asType}.
+ *
+ * When called, the adapter replaces its trailing {@code arrayLength}
+ * arguments by a single new array of type {@code arrayType}, whose elements
+ * comprise (in order) the replaced arguments.
+ * Finally the target is called.
+ * What the target eventually returns is returned unchanged by the adapter.
+ *
+ * (The array may also be a shared constant when {@code arrayLength} is zero.)
+ *
+ * (Note: The {@code arrayType} is often identical to the last
+ * parameter type of the original target.
+ * It is an explicit argument for symmetry with {@code asSpreader}, and also
+ * to allow the target to use a simple {@code Object} as its last parameter type.)
+ *
+ * In order to create a collecting adapter which is not restricted to a particular
+ * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
+ * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
+ * @param arrayLength the number of arguments to collect into a new array argument
+ * @return a new method handle which collects some trailing argument
+ * into an array, before calling the original method handle
+ * @throws IllegalArgumentException if {@code arrayType} is not an array type
+ * or {@code arrayType} is not assignable to this method handle's trailing parameter type,
+ * or {@code arrayLength} is not a legal array size
+ * @throws WrongMethodTypeException if the implied {@code asType} call fails
+ * @see #asSpreader
+ * @see #asVarargsCollector
+ */
+ public MethodHandle asCollector(Class> arrayType, int arrayLength) {
+ Class> arrayElement = arrayType.getComponentType();
+ if (arrayElement == null) throw newIllegalArgumentException("not an array type");
+ MethodType oldType = type();
+ int nargs = oldType.parameterCount();
+ if (nargs == 0) throw newIllegalArgumentException("no trailing argument");
+ MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
+ newType = newType.insertParameterTypes(nargs-1,
+ java.util.Collections.>nCopies(arrayLength, arrayElement));
+ return MethodHandles.collectArguments(this, newType);
+ }
+
+ /**
+ * Makes a variable arity adapter which is able to accept
+ * any number of trailing positional arguments and collect them
+ * into an array argument.
+ *
+ * The type and behavior of the adapter will be the same as
+ * the type and behavior of the target, except that certain
+ * {@code invokeGeneric} and {@code asType} requests can lead to
+ * trailing positional arguments being collected into target's
+ * trailing parameter.
+ * Also, the last parameter type of the adapter will be
+ * {@code arrayType}, even if the target has a different
+ * last parameter type.
+ *
+ * When called with {@link #invokeExact invokeExact}, the adapter invokes
+ * the target with no argument changes.
+ * (Note: This behavior is different from a
+ * {@linkplain #asCollector fixed arity collector},
+ * since it accepts a whole array of indeterminate length,
+ * rather than a fixed number of arguments.)
+ *
+ * When called with {@link #invokeGeneric invokeGeneric}, if the caller
+ * type is the same as the adapter, the adapter invokes the target as with
+ * {@code invokeExact}.
+ * (This is the normal behavior for {@code invokeGeneric} when types match.)
+ *
+ * Otherwise, if the caller and adapter arity are the same, and the
+ * trailing parameter type of the caller is a reference type identical to
+ * or assignable to the trailing parameter type of the adapter,
+ * the arguments and return values are converted pairwise,
+ * as if by {@link MethodHandles#convertArguments convertArguments}.
+ * (This is also normal behavior for {@code invokeGeneric} in such a case.)
+ *
+ * Otherwise, the arities differ, or the adapter's trailing parameter
+ * type is not assignable from the corresponding caller type.
+ * In this case, the adapter replaces all trailing arguments from
+ * the original trailing argument position onward, by
+ * a new array of type {@code arrayType}, whose elements
+ * comprise (in order) the replaced arguments.
+ *
+ * The caller type must provides as least enough arguments,
+ * and of the correct type, to satisfy the target's requirement for
+ * positional arguments before the trailing array argument.
+ * Thus, the caller must supply, at a minimum, {@code N-1} arguments,
+ * where {@code N} is the arity of the target.
+ * Also, there must exist conversions from the incoming arguments
+ * to the target's arguments.
+ * As with other uses of {@code invokeGeneric}, if these basic
+ * requirements are not fulfilled, a {@code WrongMethodTypeException}
+ * may be thrown.
+ *
+ * In all cases, what the target eventually returns is returned unchanged by the adapter.
+ *
+ * In the final case, it is exactly as if the target method handle were
+ * temporarily adapted with a {@linkplain #asCollector fixed arity collector}
+ * to the arity required by the caller type.
+ * (As with {@code asCollector}, if the array length is zero,
+ * a shared constant may be used instead of a new array.
+ * If the implied call to {@code asCollector} would throw
+ * an {@code IllegalArgumentException} or {@code WrongMethodTypeException},
+ * the call to the variable arity adapter must throw
+ * {@code WrongMethodTypeException}.)
+ *
+ * The behavior of {@link #asType asType} is also specialized for
+ * variable arity adapters, to maintain the invariant that
+ * {@code invokeGeneric} is always equivalent to an {@code asType}
+ * call to adjust the target type, followed by {@code invokeExact}.
+ * Therefore, a variable arity adapter responds
+ * to an {@code asType} request by building a fixed arity collector,
+ * if and only if the adapter and requested type differ either
+ * in arity or trailing argument type.
+ * The resulting fixed arity collector has its type further adjusted
+ * (if necessary) to the requested type by pairwise conversion,
+ * as if by another application of {@code asType}.
+ *
+ * When a method handle is obtained by executing an {@code ldc} instruction
+ * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
+ * as a variable arity method (with the modifier bit {@code 0x0080}),
+ * the method handle will accept multiple arities, as if the method handle
+ * constant were created by means of a call to {@code asVarargsCollector}.
+ *
+ * In order to create a collecting adapter which collects a predetermined
+ * number of arguments, and whose type reflects this predetermined number,
+ * use {@link #asCollector asCollector} instead.
+ *
+ * No method handle transformations produce new method handles with
+ * variable arity, unless they are documented as doing so.
+ * Therefore, besides {@code asVarargsCollector},
+ * all methods in {@code MethodHandle} and {@code MethodHandles}
+ * will return a method handle with fixed arity,
+ * except in the cases where they are specified to return their original
+ * operand (e.g., {@code asType} of the method handle's own type).
+ *
+ * Calling {@code asVarargsCollector} on a method handle which is already
+ * of variable arity will produce a method handle with the same type and behavior.
+ * It may (or may not) return the original variable arity method handle.
+ *
+ * Here is an example, of a list-making variable arity method handle:
+ *
+MethodHandle asList = publicLookup()
+ .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
+ .asVarargsCollector(Object[].class);
+assertEquals("[]", asList.invokeGeneric().toString());
+assertEquals("[1]", asList.invokeGeneric(1).toString());
+assertEquals("[two, too]", asList.invokeGeneric("two", "too").toString());
+Object[] argv = { "three", "thee", "tee" };
+assertEquals("[three, thee, tee]", asList.invokeGeneric(argv).toString());
+List ls = (List) asList.invokeGeneric((Object)argv);
+assertEquals(1, ls.size());
+assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
+ *
+ *
+ * Discussion:
+ * These rules are designed as a dynamically-typed variation
+ * of the Java rules for variable arity methods.
+ * In both cases, callers to a variable arity method or method handle
+ * can either pass zero or more positional arguments, or else pass
+ * pre-collected arrays of any length. Users should be aware of the
+ * special role of the final argument, and of the effect of a
+ * type match on that final argument, which determines whether
+ * or not a single trailing argument is interpreted as a whole
+ * array or a single element of an array to be collected.
+ * Note that the dynamic type of the trailing argument has no
+ * effect on this decision, only a comparison between the static
+ * type descriptor of the call site and the type of the method handle.)
+ *
+ * As a result of the previously stated rules, the variable arity behavior
+ * of a method handle may be suppressed, by binding it to the exact invoker
+ * of its own type, as follows:
+ *
+MethodHandle vamh = publicLookup()
+ .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
+ .asVarargsCollector(Object[].class);
+MethodHandle mh = MethodHandles.exactInvoker(vamh.type()).bindTo(vamh);
+assert(vamh.type().equals(mh.type()));
+assertEquals("[1, 2, 3]", vamh.invokeGeneric(1,2,3).toString());
+boolean failed = false;
+try { mh.invokeGeneric(1,2,3); }
+catch (WrongMethodTypeException ex) { failed = true; }
+assert(failed);
+ *
+ * This transformation has no behavioral effect if the method handle is
+ * not of variable arity.
+ *
+ * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
+ * @return a new method handle which can collect any number of trailing arguments
+ * into an array, before calling the original method handle
+ * @throws IllegalArgumentException if {@code arrayType} is not an array type
+ * or {@code arrayType} is not assignable to this method handle's trailing parameter type
+ * @see #asCollector
+ * @see #isVarargsCollector
+ */
+ public MethodHandle asVarargsCollector(Class> arrayType) {
+ Class> arrayElement = arrayType.getComponentType();
+ if (arrayElement == null) throw newIllegalArgumentException("not an array type");
+ return MethodHandles.asVarargsCollector(this, arrayType);
+ }
+
+ /**
+ * Determines if this method handle
+ * supports {@linkplain #asVarargsCollector variable arity} calls.
+ * Such method handles arise from the following sources:
+ *
+ * a call to {@linkplain #asVarargsCollector asVarargsCollector}
+ * a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
+ * which resolves to a variable arity Java method or constructor
+ * an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
+ * which resolves to a variable arity Java method or constructor
+ *
+ * @return true if this method handle accepts more than one arity of {@code invokeGeneric} calls
+ * @see #asVarargsCollector
+ */
+ public boolean isVarargsCollector() {
+ return false;
+ }
+
+ /**
+ * Binds a value {@code x} to the first argument of a method handle, without invoking it.
+ * The new method handle adapts, as its target ,
+ * the current method handle by binding it to the given argument.
+ * The type of the bound handle will be
+ * the same as the type of the target, except that a single leading
+ * reference parameter will be omitted.
+ *
+ * When called, the bound handle inserts the given value {@code x}
+ * as a new leading argument to the target. The other arguments are
+ * also passed unchanged.
+ * What the target eventually returns is returned unchanged by the bound handle.
+ *
+ * The reference {@code x} must be convertible to the first parameter
+ * type of the target.
+ *
+ * (Note: Because method handles are immutable, the target method handle
+ * retains its original type and behavior.)
+ * @param x the value to bind to the first argument of the target
+ * @return a new method handle which prepends the given value to the incoming
+ * argument list, before calling the original method handle
+ * @throws IllegalArgumentException if the target does not have a
+ * leading parameter type that is a reference type
+ * @throws ClassCastException if {@code x} cannot be converted
+ * to the leading parameter type of the target
+ * @see MethodHandles#insertArguments
+ */
+ public MethodHandle bindTo(Object x) {
+ Class> ptype;
+ if (type().parameterCount() == 0 ||
+ (ptype = type().parameterType(0)).isPrimitive())
+ throw newIllegalArgumentException("no leading reference parameter", x);
+ x = MethodHandles.checkValue(ptype, x);
+ // Cf. MethodHandles.insertArguments for the following logic:
+ MethodHandle bmh = MethodHandleImpl.bindReceiver(this, x);
+ if (bmh != null) return bmh;
+ return MethodHandleImpl.bindArgument(this, 0, x);
+ }
+
+ /**
+ * Returns a string representation of the method handle,
+ * starting with the string {@code "MethodHandle"} and
+ * ending with the string representation of the method handle's type.
+ * In other words, this method returns a string equal to the value of:
+ *
+ * "MethodHandle" + type().toString()
+ *
+ *
+ * (Note: Future releases of this API may add further information
+ * to the string representation.
+ * Therefore, the present syntax should not be parsed by applications.)
+ *
+ * @return a string representation of the method handle
+ */
+ @Override
+ public String toString() {
+ return getNameString(this);
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,1106 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.VerifyType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import sun.invoke.empty.Empty;
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.Wrapper;
+import sun.misc.Unsafe;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * Trusted implementation code for MethodHandle.
+ * @author jrose
+ */
+/*non-public*/ abstract class MethodHandleImpl {
+ /// Factory methods to create method handles:
+
+ private static final MemberName.Factory LOOKUP = MemberName.Factory.INSTANCE;
+
+ static void initStatics() {
+ // Trigger preceding sequence.
+ }
+
+ /** Look up a given method.
+ * Callable only from sun.invoke and related packages.
+ *
+ * The resulting method handle type will be of the given type,
+ * with a receiver type {@code rcvc} prepended if the member is not static.
+ *
+ * Access checks are made as of the given lookup class.
+ * In particular, if the method is protected and {@code defc} is in a
+ * different package from the lookup class, then {@code rcvc} must be
+ * the lookup class or a subclass.
+ * @param token Proof that the lookup class has access to this package.
+ * @param member Resolved method or constructor to call.
+ * @param name Name of the desired method.
+ * @param rcvc Receiver type of desired non-static method (else null)
+ * @param doDispatch whether the method handle will test the receiver type
+ * @param lookupClass access-check relative to this class
+ * @return a direct handle to the matching method
+ * @throws IllegalAccessException if the given method cannot be accessed by the lookup class
+ */
+ static
+ MethodHandle findMethod(MemberName method,
+ boolean doDispatch, Class> lookupClass) throws IllegalAccessException {
+ MethodType mtype = method.getMethodType();
+ if (!method.isStatic()) {
+ // adjust the advertised receiver type to be exactly the one requested
+ // (in the case of invokespecial, this will be the calling class)
+ Class> recvType = method.getDeclaringClass();
+ mtype = mtype.insertParameterTypes(0, recvType);
+ }
+ DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass);
+ if (!mh.isValid())
+ throw method.makeAccessException("no access", lookupClass);
+ assert(mh.type() == mtype);
+ if (!method.isVarargs())
+ return mh;
+ else
+ return mh.asVarargsCollector(mtype.parameterType(mtype.parameterCount()-1));
+ }
+
+ static
+ MethodHandle makeAllocator(MethodHandle rawConstructor) {
+ MethodType rawConType = rawConstructor.type();
+ // Wrap the raw (unsafe) constructor with the allocation of a suitable object.
+ MethodHandle allocator
+ = AllocateObject.make(rawConType.parameterType(0), rawConstructor);
+ assert(allocator.type()
+ .equals(rawConType.dropParameterTypes(0, 1).changeReturnType(rawConType.parameterType(0))));
+ return allocator;
+ }
+
+ static final class AllocateObject extends BoundMethodHandle {
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+ private final Class allocateClass;
+ private final MethodHandle rawConstructor;
+
+ private AllocateObject(MethodHandle invoker,
+ Class allocateClass, MethodHandle rawConstructor) {
+ super(invoker);
+ this.allocateClass = allocateClass;
+ this.rawConstructor = rawConstructor;
+ }
+ static MethodHandle make(Class> allocateClass, MethodHandle rawConstructor) {
+ MethodType rawConType = rawConstructor.type();
+ assert(rawConType.parameterType(0) == allocateClass);
+ MethodType newType = rawConType.dropParameterTypes(0, 1).changeReturnType(allocateClass);
+ int nargs = rawConType.parameterCount() - 1;
+ if (nargs < INVOKES.length) {
+ MethodHandle invoke = INVOKES[nargs];
+ MethodType conType = CON_TYPES[nargs];
+ MethodHandle gcon = convertArguments(rawConstructor, conType, rawConType, null);
+ if (gcon == null) return null;
+ MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
+ assert(galloc.type() == newType.generic());
+ return convertArguments(galloc, newType, galloc.type(), null);
+ } else {
+ MethodHandle invoke = VARARGS_INVOKE;
+ MethodType conType = CON_TYPES[nargs];
+ MethodHandle gcon = spreadArguments(rawConstructor, conType, 1);
+ if (gcon == null) return null;
+ MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
+ return collectArguments(galloc, newType, 1, null);
+ }
+ }
+ @Override
+ public String toString() {
+ return addTypeString(allocateClass.getSimpleName(), this);
+ }
+ @SuppressWarnings("unchecked")
+ private C allocate() throws InstantiationException {
+ return (C) unsafe.allocateInstance(allocateClass);
+ }
+ private C invoke_V(Object... av) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, av);
+ return obj;
+ }
+ private C invoke_L0() throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj);
+ return obj;
+ }
+ private C invoke_L1(Object a0) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, a0);
+ return obj;
+ }
+ private C invoke_L2(Object a0, Object a1) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, a0, a1);
+ return obj;
+ }
+ private C invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, a0, a1, a2);
+ return obj;
+ }
+ private C invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3);
+ return obj;
+ }
+ private C invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4);
+ return obj;
+ }
+ private C invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5);
+ return obj;
+ }
+ private C invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5, a6);
+ return obj;
+ }
+ private C invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ C obj = allocate();
+ rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5, a6, a7);
+ return obj;
+ }
+ static MethodHandle[] makeInvokes() {
+ ArrayList invokes = new ArrayList();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = invokes.size();
+ String name = "invoke_L"+nargs;
+ MethodHandle invoke = null;
+ try {
+ invoke = lookup.findVirtual(AllocateObject.class, name, MethodType.genericMethodType(nargs));
+ } catch (ReflectiveOperationException ex) {
+ }
+ if (invoke == null) break;
+ invokes.add(invoke);
+ }
+ assert(invokes.size() == 9); // current number of methods
+ return invokes.toArray(new MethodHandle[0]);
+ };
+ static final MethodHandle[] INVOKES = makeInvokes();
+ // For testing use this:
+ //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
+ static final MethodHandle VARARGS_INVOKE;
+ static {
+ try {
+ VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "invoke_V", MethodType.genericMethodType(0, true));
+ } catch (ReflectiveOperationException ex) {
+ throw uncaughtException(ex);
+ }
+ }
+ // Corresponding generic constructor types:
+ static final MethodType[] CON_TYPES = new MethodType[INVOKES.length];
+ static {
+ for (int i = 0; i < INVOKES.length; i++)
+ CON_TYPES[i] = makeConType(INVOKES[i]);
+ }
+ static final MethodType VARARGS_CON_TYPE = makeConType(VARARGS_INVOKE);
+ static MethodType makeConType(MethodHandle invoke) {
+ MethodType invType = invoke.type();
+ return invType.changeParameterType(0, Object.class).changeReturnType(void.class);
+ }
+ }
+
+ static
+ MethodHandle accessField(MemberName member, boolean isSetter,
+ Class> lookupClass) {
+ // Use sun. misc.Unsafe to dig up the dirt on the field.
+ MethodHandle mh = new FieldAccessor(member, isSetter);
+ return mh;
+ }
+
+ static
+ MethodHandle accessArrayElement(Class> arrayClass, boolean isSetter) {
+ if (!arrayClass.isArray())
+ throw newIllegalArgumentException("not an array: "+arrayClass);
+ Class> elemClass = arrayClass.getComponentType();
+ MethodHandle[] mhs = FieldAccessor.ARRAY_CACHE.get(elemClass);
+ if (mhs == null) {
+ if (!FieldAccessor.doCache(elemClass))
+ return FieldAccessor.ahandle(arrayClass, isSetter);
+ mhs = new MethodHandle[] {
+ FieldAccessor.ahandle(arrayClass, false),
+ FieldAccessor.ahandle(arrayClass, true)
+ };
+ if (mhs[0].type().parameterType(0) == Class.class) {
+ mhs[0] = MethodHandles.insertArguments(mhs[0], 0, elemClass);
+ mhs[1] = MethodHandles.insertArguments(mhs[1], 0, elemClass);
+ }
+ synchronized (FieldAccessor.ARRAY_CACHE) {} // memory barrier
+ FieldAccessor.ARRAY_CACHE.put(elemClass, mhs);
+ }
+ return mhs[isSetter ? 1 : 0];
+ }
+
+ static final class FieldAccessor extends BoundMethodHandle {
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ final Object base; // for static refs only
+ final long offset;
+ final String name;
+
+ FieldAccessor(MemberName field, boolean isSetter) {
+ super(fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic()));
+ this.offset = (long) field.getVMIndex();
+ this.name = field.getName();
+ this.base = staticBase(field);
+ }
+ @Override
+ public String toString() { return addTypeString(name, this); }
+
+ int getFieldI(C obj) { return unsafe.getInt(obj, offset); }
+ void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); }
+ long getFieldJ(C obj) { return unsafe.getLong(obj, offset); }
+ void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); }
+ float getFieldF(C obj) { return unsafe.getFloat(obj, offset); }
+ void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); }
+ double getFieldD(C obj) { return unsafe.getDouble(obj, offset); }
+ void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); }
+ boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); }
+ void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
+ byte getFieldB(C obj) { return unsafe.getByte(obj, offset); }
+ void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); }
+ short getFieldS(C obj) { return unsafe.getShort(obj, offset); }
+ void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); }
+ char getFieldC(C obj) { return unsafe.getChar(obj, offset); }
+ void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); }
+ @SuppressWarnings("unchecked")
+ V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); }
+ @SuppressWarnings("unchecked")
+ void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); }
+ // cast (V) is OK here, since we wrap convertArguments around the MH.
+
+ static Object staticBase(MemberName field) {
+ if (!field.isStatic()) return null;
+ Class c = field.getDeclaringClass();
+ java.lang.reflect.Field f;
+ try {
+ // FIXME: Should not have to create 'f' to get this value.
+ f = c.getDeclaredField(field.getName());
+ return unsafe.staticFieldBase(f);
+ } catch (Exception ee) {
+ throw uncaughtException(ee);
+ }
+ }
+
+ int getStaticI() { return unsafe.getInt(base, offset); }
+ void setStaticI(int x) { unsafe.putInt(base, offset, x); }
+ long getStaticJ() { return unsafe.getLong(base, offset); }
+ void setStaticJ(long x) { unsafe.putLong(base, offset, x); }
+ float getStaticF() { return unsafe.getFloat(base, offset); }
+ void setStaticF(float x) { unsafe.putFloat(base, offset, x); }
+ double getStaticD() { return unsafe.getDouble(base, offset); }
+ void setStaticD(double x) { unsafe.putDouble(base, offset, x); }
+ boolean getStaticZ() { return unsafe.getBoolean(base, offset); }
+ void setStaticZ(boolean x) { unsafe.putBoolean(base, offset, x); }
+ byte getStaticB() { return unsafe.getByte(base, offset); }
+ void setStaticB(byte x) { unsafe.putByte(base, offset, x); }
+ short getStaticS() { return unsafe.getShort(base, offset); }
+ void setStaticS(short x) { unsafe.putShort(base, offset, x); }
+ char getStaticC() { return unsafe.getChar(base, offset); }
+ void setStaticC(char x) { unsafe.putChar(base, offset, x); }
+ V getStaticL() { return (V) unsafe.getObject(base, offset); }
+ void setStaticL(V x) { unsafe.putObject(base, offset, x); }
+
+ static String fname(Class> vclass, boolean isSetter, boolean isStatic) {
+ String stem;
+ if (!isStatic)
+ stem = (!isSetter ? "getField" : "setField");
+ else
+ stem = (!isSetter ? "getStatic" : "setStatic");
+ return stem + Wrapper.basicTypeChar(vclass);
+ }
+ static MethodType ftype(Class> cclass, Class> vclass, boolean isSetter, boolean isStatic) {
+ MethodType type;
+ if (!isStatic) {
+ if (!isSetter)
+ return MethodType.methodType(vclass, cclass);
+ else
+ return MethodType.methodType(void.class, cclass, vclass);
+ } else {
+ if (!isSetter)
+ return MethodType.methodType(vclass);
+ else
+ return MethodType.methodType(void.class, vclass);
+ }
+ }
+ static MethodHandle fhandle(Class> cclass, Class> vclass, boolean isSetter, boolean isStatic) {
+ String name = FieldAccessor.fname(vclass, isSetter, isStatic);
+ if (cclass.isPrimitive()) throw newIllegalArgumentException("primitive "+cclass);
+ Class> ecclass = Object.class; //erase this type
+ Class> evclass = vclass;
+ if (!evclass.isPrimitive()) evclass = Object.class;
+ MethodType type = FieldAccessor.ftype(ecclass, evclass, isSetter, isStatic);
+ MethodHandle mh;
+ try {
+ mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
+ } catch (ReflectiveOperationException ex) {
+ throw uncaughtException(ex);
+ }
+ if (evclass != vclass || (!isStatic && ecclass != cclass)) {
+ MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic);
+ strongType = strongType.insertParameterTypes(0, FieldAccessor.class);
+ mh = MethodHandles.convertArguments(mh, strongType);
+ }
+ return mh;
+ }
+
+ /// Support for array element access
+ static final HashMap, MethodHandle[]> ARRAY_CACHE =
+ new HashMap, MethodHandle[]>();
+ // FIXME: Cache on the classes themselves, not here.
+ static boolean doCache(Class> elemClass) {
+ if (elemClass.isPrimitive()) return true;
+ ClassLoader cl = elemClass.getClassLoader();
+ return cl == null || cl == ClassLoader.getSystemClassLoader();
+ }
+ static int getElementI(int[] a, int i) { return a[i]; }
+ static void setElementI(int[] a, int i, int x) { a[i] = x; }
+ static long getElementJ(long[] a, int i) { return a[i]; }
+ static void setElementJ(long[] a, int i, long x) { a[i] = x; }
+ static float getElementF(float[] a, int i) { return a[i]; }
+ static void setElementF(float[] a, int i, float x) { a[i] = x; }
+ static double getElementD(double[] a, int i) { return a[i]; }
+ static void setElementD(double[] a, int i, double x) { a[i] = x; }
+ static boolean getElementZ(boolean[] a, int i) { return a[i]; }
+ static void setElementZ(boolean[] a, int i, boolean x) { a[i] = x; }
+ static byte getElementB(byte[] a, int i) { return a[i]; }
+ static void setElementB(byte[] a, int i, byte x) { a[i] = x; }
+ static short getElementS(short[] a, int i) { return a[i]; }
+ static void setElementS(short[] a, int i, short x) { a[i] = x; }
+ static char getElementC(char[] a, int i) { return a[i]; }
+ static void setElementC(char[] a, int i, char x) { a[i] = x; }
+ static Object getElementL(Object[] a, int i) { return a[i]; }
+ static void setElementL(Object[] a, int i, Object x) { a[i] = x; }
+ static V getElementL(Class aclass, V[] a, int i) { return aclass.cast(a)[i]; }
+ static void setElementL(Class aclass, V[] a, int i, V x) { aclass.cast(a)[i] = x; }
+
+ static String aname(Class> aclass, boolean isSetter) {
+ Class> vclass = aclass.getComponentType();
+ if (vclass == null) throw new IllegalArgumentException();
+ return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(vclass);
+ }
+ static MethodType atype(Class> aclass, boolean isSetter) {
+ Class> vclass = aclass.getComponentType();
+ if (!isSetter)
+ return MethodType.methodType(vclass, aclass, int.class);
+ else
+ return MethodType.methodType(void.class, aclass, int.class, vclass);
+ }
+ static MethodHandle ahandle(Class> aclass, boolean isSetter) {
+ Class> vclass = aclass.getComponentType();
+ String name = FieldAccessor.aname(aclass, isSetter);
+ Class> caclass = null;
+ if (!vclass.isPrimitive() && vclass != Object.class) {
+ caclass = aclass;
+ aclass = Object[].class;
+ vclass = Object.class;
+ }
+ MethodType type = FieldAccessor.atype(aclass, isSetter);
+ if (caclass != null)
+ type = type.insertParameterTypes(0, Class.class);
+ MethodHandle mh;
+ try {
+ mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
+ } catch (ReflectiveOperationException ex) {
+ throw uncaughtException(ex);
+ }
+ if (caclass != null) {
+ MethodType strongType = FieldAccessor.atype(caclass, isSetter);
+ mh = MethodHandles.insertArguments(mh, 0, caclass);
+ mh = MethodHandles.convertArguments(mh, strongType);
+ }
+ return mh;
+ }
+ }
+
+ /** Bind a predetermined first argument to the given direct method handle.
+ * Callable only from MethodHandles.
+ * @param token Proof that the caller has access to this package.
+ * @param target Any direct method handle.
+ * @param receiver Receiver (or first static method argument) to pre-bind.
+ * @return a BoundMethodHandle for the given DirectMethodHandle, or null if it does not exist
+ */
+ static
+ MethodHandle bindReceiver(MethodHandle target, Object receiver) {
+ if (target instanceof AdapterMethodHandle &&
+ ((AdapterMethodHandle)target).conversionOp() == MethodHandleNatives.Constants.OP_RETYPE_ONLY
+ ) {
+ Object info = MethodHandleNatives.getTargetInfo(target);
+ if (info instanceof DirectMethodHandle) {
+ DirectMethodHandle dmh = (DirectMethodHandle) info;
+ if (receiver == null ||
+ dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) {
+ MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0);
+ MethodType newType = target.type().dropParameterTypes(0, 1);
+ return convertArguments(bmh, newType, bmh.type(), null);
+ }
+ }
+ }
+ if (target instanceof DirectMethodHandle)
+ return new BoundMethodHandle((DirectMethodHandle)target, receiver, 0);
+ return null; // let caller try something else
+ }
+
+ /** Bind a predetermined argument to the given arbitrary method handle.
+ * Callable only from MethodHandles.
+ * @param token Proof that the caller has access to this package.
+ * @param target Any method handle.
+ * @param receiver Argument (which can be a boxed primitive) to pre-bind.
+ * @return a suitable BoundMethodHandle
+ */
+ static
+ MethodHandle bindArgument(MethodHandle target, int argnum, Object receiver) {
+ return new BoundMethodHandle(target, receiver, argnum);
+ }
+
+ static MethodHandle convertArguments(MethodHandle target,
+ MethodType newType,
+ MethodType oldType,
+ int[] permutationOrNull) {
+ assert(oldType.parameterCount() == target.type().parameterCount());
+ if (permutationOrNull != null) {
+ int outargs = oldType.parameterCount(), inargs = newType.parameterCount();
+ if (permutationOrNull.length != outargs)
+ throw newIllegalArgumentException("wrong number of arguments in permutation");
+ // Make the individual outgoing argument types match up first.
+ Class>[] callTypeArgs = new Class>[outargs];
+ for (int i = 0; i < outargs; i++)
+ callTypeArgs[i] = newType.parameterType(permutationOrNull[i]);
+ MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs);
+ target = convertArguments(target, callType, oldType, null);
+ assert(target != null);
+ oldType = target.type();
+ List goal = new ArrayList(); // i*TOKEN
+ List state = new ArrayList(); // i*TOKEN
+ List drops = new ArrayList(); // not tokens
+ List dups = new ArrayList(); // not tokens
+ final int TOKEN = 10; // to mark items which are symbolic only
+ // state represents the argument values coming into target
+ for (int i = 0; i < outargs; i++) {
+ state.add(permutationOrNull[i] * TOKEN);
+ }
+ // goal represents the desired state
+ for (int i = 0; i < inargs; i++) {
+ if (state.contains(i * TOKEN)) {
+ goal.add(i * TOKEN);
+ } else {
+ // adapter must initially drop all unused arguments
+ drops.add(i);
+ }
+ }
+ // detect duplications
+ while (state.size() > goal.size()) {
+ for (int i2 = 0; i2 < state.size(); i2++) {
+ int arg1 = state.get(i2);
+ int i1 = state.indexOf(arg1);
+ if (i1 != i2) {
+ // found duplicate occurrence at i2
+ int arg2 = (inargs++) * TOKEN;
+ state.set(i2, arg2);
+ dups.add(goal.indexOf(arg1));
+ goal.add(arg2);
+ }
+ }
+ }
+ assert(state.size() == goal.size());
+ int size = goal.size();
+ while (!state.equals(goal)) {
+ // Look for a maximal sequence of adjacent misplaced arguments,
+ // and try to rotate them into place.
+ int bestRotArg = -10 * TOKEN, bestRotLen = 0;
+ int thisRotArg = -10 * TOKEN, thisRotLen = 0;
+ for (int i = 0; i < size; i++) {
+ int arg = state.get(i);
+ // Does this argument match the current run?
+ if (arg == thisRotArg + TOKEN) {
+ thisRotArg = arg;
+ thisRotLen += 1;
+ if (bestRotLen < thisRotLen) {
+ bestRotLen = thisRotLen;
+ bestRotArg = thisRotArg;
+ }
+ } else {
+ // The old sequence (if any) stops here.
+ thisRotLen = 0;
+ thisRotArg = -10 * TOKEN;
+ // But maybe a new one starts here also.
+ int wantArg = goal.get(i);
+ final int MAX_ARG_ROTATION = AdapterMethodHandle.MAX_ARG_ROTATION;
+ if (arg != wantArg &&
+ arg >= wantArg - TOKEN * MAX_ARG_ROTATION &&
+ arg <= wantArg + TOKEN * MAX_ARG_ROTATION) {
+ thisRotArg = arg;
+ thisRotLen = 1;
+ }
+ }
+ }
+ if (bestRotLen >= 2) {
+ // Do a rotation if it can improve argument positioning
+ // by at least 2 arguments. This is not always optimal,
+ // but it seems to catch common cases.
+ int dstEnd = state.indexOf(bestRotArg);
+ int srcEnd = goal.indexOf(bestRotArg);
+ int rotBy = dstEnd - srcEnd;
+ int dstBeg = dstEnd - (bestRotLen - 1);
+ int srcBeg = srcEnd - (bestRotLen - 1);
+ assert((dstEnd | dstBeg | srcEnd | srcBeg) >= 0); // no negs
+ // Make a span which covers both source and destination.
+ int rotBeg = Math.min(dstBeg, srcBeg);
+ int rotEnd = Math.max(dstEnd, srcEnd);
+ int score = 0;
+ for (int i = rotBeg; i <= rotEnd; i++) {
+ if ((int)state.get(i) != (int)goal.get(i))
+ score += 1;
+ }
+ List rotSpan = state.subList(rotBeg, rotEnd+1);
+ Collections.rotate(rotSpan, -rotBy); // reverse direction
+ for (int i = rotBeg; i <= rotEnd; i++) {
+ if ((int)state.get(i) != (int)goal.get(i))
+ score -= 1;
+ }
+ if (score >= 2) {
+ // Improved at least two argument positions. Do it.
+ List> ptypes = Arrays.asList(oldType.parameterArray());
+ Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy);
+ MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes);
+ MethodHandle nextTarget
+ = AdapterMethodHandle.makeRotateArguments(rotType, target,
+ rotBeg, rotSpan.size(), rotBy);
+ if (nextTarget != null) {
+ //System.out.println("Rot: "+rotSpan+" by "+rotBy);
+ target = nextTarget;
+ oldType = rotType;
+ continue;
+ }
+ }
+ // Else de-rotate, and drop through to the swap-fest.
+ Collections.rotate(rotSpan, rotBy);
+ }
+
+ // Now swap like the wind!
+ List> ptypes = Arrays.asList(oldType.parameterArray());
+ for (int i = 0; i < size; i++) {
+ // What argument do I want here?
+ int arg = goal.get(i);
+ if (arg != state.get(i)) {
+ // Where is it now?
+ int j = state.indexOf(arg);
+ Collections.swap(ptypes, i, j);
+ MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes);
+ target = AdapterMethodHandle.makeSwapArguments(swapType, target, i, j);
+ if (target == null) throw newIllegalArgumentException("cannot swap");
+ assert(target.type() == swapType);
+ oldType = swapType;
+ Collections.swap(state, i, j);
+ }
+ }
+ // One pass of swapping must finish the job.
+ assert(state.equals(goal));
+ }
+ while (!dups.isEmpty()) {
+ // Grab a contiguous trailing sequence of dups.
+ int grab = dups.size() - 1;
+ int dupArgPos = dups.get(grab), dupArgCount = 1;
+ while (grab - 1 >= 0) {
+ int dup0 = dups.get(grab - 1);
+ if (dup0 != dupArgPos - 1) break;
+ dupArgPos -= 1;
+ dupArgCount += 1;
+ grab -= 1;
+ }
+ //if (dupArgCount > 1) System.out.println("Dup: "+dups.subList(grab, dups.size()));
+ dups.subList(grab, dups.size()).clear();
+ // In the new target type drop that many args from the tail:
+ List> ptypes = oldType.parameterList();
+ ptypes = ptypes.subList(0, ptypes.size() - dupArgCount);
+ MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes);
+ target = AdapterMethodHandle.makeDupArguments(dupType, target, dupArgPos, dupArgCount);
+ if (target == null)
+ throw newIllegalArgumentException("cannot dup");
+ oldType = target.type();
+ }
+ while (!drops.isEmpty()) {
+ // Grab a contiguous initial sequence of drops.
+ int dropArgPos = drops.get(0), dropArgCount = 1;
+ while (dropArgCount < drops.size()) {
+ int drop1 = drops.get(dropArgCount);
+ if (drop1 != dropArgPos + dropArgCount) break;
+ dropArgCount += 1;
+ }
+ //if (dropArgCount > 1) System.out.println("Drop: "+drops.subList(0, dropArgCount));
+ drops.subList(0, dropArgCount).clear();
+ List> dropTypes = newType.parameterList()
+ .subList(dropArgPos, dropArgPos + dropArgCount);
+ MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes);
+ target = AdapterMethodHandle.makeDropArguments(dropType, target, dropArgPos, dropArgCount);
+ if (target == null) throw newIllegalArgumentException("cannot drop");
+ oldType = target.type();
+ }
+ }
+ if (newType == oldType)
+ return target;
+ if (oldType.parameterCount() != newType.parameterCount())
+ throw newIllegalArgumentException("mismatched parameter count");
+ MethodHandle res = AdapterMethodHandle.makePairwiseConvert(newType, target);
+ if (res != null)
+ return res;
+ int argc = oldType.parameterCount();
+ // The JVM can't do it directly, so fill in the gap with a Java adapter.
+ // TO DO: figure out what to put here from case-by-case experience
+ // Use a heavier method: Convert all the arguments to Object,
+ // then back to the desired types. We might have to use Java-based
+ // method handles to do this.
+ MethodType objType = MethodType.genericMethodType(argc);
+ MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(objType, target);
+ if (objTarget == null)
+ objTarget = FromGeneric.make(target);
+ res = AdapterMethodHandle.makePairwiseConvert(newType, objTarget);
+ if (res != null)
+ return res;
+ return ToGeneric.make(newType, objTarget);
+ }
+
+ static MethodHandle spreadArguments(MethodHandle target,
+ MethodType newType,
+ int spreadArg) {
+ // TO DO: maybe allow the restarg to be Object and implicitly cast to Object[]
+ MethodType oldType = target.type();
+ // spread the last argument of newType to oldType
+ int spreadCount = oldType.parameterCount() - spreadArg;
+ Class spreadArgType = Object[].class;
+ MethodHandle res = AdapterMethodHandle.makeSpreadArguments(newType, target, spreadArgType, spreadArg, spreadCount);
+ if (res != null)
+ return res;
+ // try an intermediate adapter
+ Class> spreadType = null;
+ if (spreadArg < 0 || spreadArg >= newType.parameterCount()
+ || !VerifyType.isSpreadArgType(spreadType = newType.parameterType(spreadArg)))
+ throw newIllegalArgumentException("no restarg in "+newType);
+ Class>[] ptypes = oldType.parameterArray();
+ for (int i = 0; i < spreadCount; i++)
+ ptypes[spreadArg + i] = VerifyType.spreadArgElementType(spreadType, i);
+ MethodType midType = MethodType.methodType(newType.returnType(), ptypes);
+ // after spreading, some arguments may need further conversion
+ MethodHandle target2 = convertArguments(target, midType, oldType, null);
+ if (target2 == null)
+ throw new UnsupportedOperationException("NYI: convert "+midType+" =calls=> "+oldType);
+ res = AdapterMethodHandle.makeSpreadArguments(newType, target2, spreadArgType, spreadArg, spreadCount);
+ if (res != null)
+ return res;
+ res = SpreadGeneric.make(target2, spreadCount);
+ if (res != null)
+ res = convertArguments(res, newType, res.type(), null);
+ return res;
+ }
+
+ static MethodHandle collectArguments(MethodHandle target,
+ MethodType newType,
+ int collectArg,
+ MethodHandle collector) {
+ MethodType oldType = target.type(); // (a...,c)=>r
+ if (collector == null) {
+ int numCollect = newType.parameterCount() - oldType.parameterCount() + 1;
+ collector = ValueConversions.varargsArray(numCollect);
+ }
+ // newType // (a..., b...)=>r
+ MethodType colType = collector.type(); // (b...)=>c
+ // oldType // (a..., b...)=>r
+ assert(newType.parameterCount() == collectArg + colType.parameterCount());
+ assert(oldType.parameterCount() == collectArg + 1);
+ MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, null);
+ MethodHandle gcollector = convertArguments(collector, colType.generic(), colType, null);
+ if (gtarget == null || gcollector == null) return null;
+ MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget);
+ MethodHandle result = convertArguments(gresult, newType, gresult.type(), null);
+ return result;
+ }
+
+ static MethodHandle filterArgument(MethodHandle target,
+ int pos,
+ MethodHandle filter) {
+ MethodType ttype = target.type(), gttype = ttype.generic();
+ if (ttype != gttype) {
+ target = convertArguments(target, gttype, ttype, null);
+ ttype = gttype;
+ }
+ MethodType ftype = filter.type(), gftype = ftype.generic();
+ if (ftype.parameterCount() != 1)
+ throw new InternalError();
+ if (ftype != gftype) {
+ filter = convertArguments(filter, gftype, ftype, null);
+ ftype = gftype;
+ }
+ if (ftype == ttype) {
+ // simple unary case
+ return FilterOneArgument.make(filter, target);
+ }
+ return FilterGeneric.makeArgumentFilter(pos, filter, target);
+ }
+
+ static MethodHandle foldArguments(MethodHandle target,
+ MethodType newType,
+ MethodHandle combiner) {
+ MethodType oldType = target.type();
+ MethodType ctype = combiner.type();
+ MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, null);
+ MethodHandle gcombiner = convertArguments(combiner, ctype.generic(), ctype, null);
+ if (gtarget == null || gcombiner == null) return null;
+ MethodHandle gresult = FilterGeneric.makeArgumentFolder(gcombiner, gtarget);
+ MethodHandle result = convertArguments(gresult, newType, gresult.type(), null);
+ return result;
+ }
+
+ static
+ MethodHandle dropArguments(MethodHandle target,
+ MethodType newType, int argnum) {
+ int drops = newType.parameterCount() - target.type().parameterCount();
+ MethodHandle res = AdapterMethodHandle.makeDropArguments(newType, target, argnum, drops);
+ if (res != null)
+ return res;
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ private static class GuardWithTest extends BoundMethodHandle {
+ private final MethodHandle test, target, fallback;
+ private GuardWithTest(MethodHandle invoker,
+ MethodHandle test, MethodHandle target, MethodHandle fallback) {
+ super(invoker);
+ this.test = test;
+ this.target = target;
+ this.fallback = fallback;
+ }
+ static MethodHandle make(MethodHandle test, MethodHandle target, MethodHandle fallback) {
+ MethodType type = target.type();
+ int nargs = type.parameterCount();
+ if (nargs < INVOKES.length) {
+ MethodHandle invoke = INVOKES[nargs];
+ MethodType gtype = type.generic();
+ assert(invoke.type().dropParameterTypes(0,1) == gtype);
+ MethodHandle gtest = convertArguments(test, gtype.changeReturnType(boolean.class), test.type(), null);
+ MethodHandle gtarget = convertArguments(target, gtype, type, null);
+ MethodHandle gfallback = convertArguments(fallback, gtype, type, null);
+ if (gtest == null || gtarget == null || gfallback == null) return null;
+ MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback);
+ return convertArguments(gguard, type, gtype, null);
+ } else {
+ MethodHandle invoke = VARARGS_INVOKE;
+ MethodType gtype = MethodType.genericMethodType(1);
+ assert(invoke.type().dropParameterTypes(0,1) == gtype);
+ MethodHandle gtest = spreadArguments(test, gtype.changeReturnType(boolean.class), 0);
+ MethodHandle gtarget = spreadArguments(target, gtype, 0);
+ MethodHandle gfallback = spreadArguments(fallback, gtype, 0);
+ MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback);
+ if (gtest == null || gtarget == null || gfallback == null) return null;
+ return collectArguments(gguard, type, 0, null);
+ }
+ }
+ @Override
+ public String toString() {
+ return addTypeString(target, this);
+ }
+ private Object invoke_V(Object... av) throws Throwable {
+ if ((boolean) test.invokeExact(av))
+ return target.invokeExact(av);
+ return fallback.invokeExact(av);
+ }
+ private Object invoke_L0() throws Throwable {
+ if ((boolean) test.invokeExact())
+ return target.invokeExact();
+ return fallback.invokeExact();
+ }
+ private Object invoke_L1(Object a0) throws Throwable {
+ if ((boolean) test.invokeExact(a0))
+ return target.invokeExact(a0);
+ return fallback.invokeExact(a0);
+ }
+ private Object invoke_L2(Object a0, Object a1) throws Throwable {
+ if ((boolean) test.invokeExact(a0, a1))
+ return target.invokeExact(a0, a1);
+ return fallback.invokeExact(a0, a1);
+ }
+ private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
+ if ((boolean) test.invokeExact(a0, a1, a2))
+ return target.invokeExact(a0, a1, a2);
+ return fallback.invokeExact(a0, a1, a2);
+ }
+ private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ if ((boolean) test.invokeExact(a0, a1, a2, a3))
+ return target.invokeExact(a0, a1, a2, a3);
+ return fallback.invokeExact(a0, a1, a2, a3);
+ }
+ private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
+ if ((boolean) test.invokeExact(a0, a1, a2, a3, a4))
+ return target.invokeExact(a0, a1, a2, a3, a4);
+ return fallback.invokeExact(a0, a1, a2, a3, a4);
+ }
+ private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
+ if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5))
+ return target.invokeExact(a0, a1, a2, a3, a4, a5);
+ return fallback.invokeExact(a0, a1, a2, a3, a4, a5);
+ }
+ private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
+ if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5, a6))
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6);
+ return fallback.invokeExact(a0, a1, a2, a3, a4, a5, a6);
+ }
+ private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7))
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7);
+ return fallback.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7);
+ }
+ static MethodHandle[] makeInvokes() {
+ ArrayList invokes = new ArrayList();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = invokes.size();
+ String name = "invoke_L"+nargs;
+ MethodHandle invoke = null;
+ try {
+ invoke = lookup.findVirtual(GuardWithTest.class, name, MethodType.genericMethodType(nargs));
+ } catch (ReflectiveOperationException ex) {
+ }
+ if (invoke == null) break;
+ invokes.add(invoke);
+ }
+ assert(invokes.size() == 9); // current number of methods
+ return invokes.toArray(new MethodHandle[0]);
+ };
+ static final MethodHandle[] INVOKES = makeInvokes();
+ // For testing use this:
+ //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
+ static final MethodHandle VARARGS_INVOKE;
+ static {
+ try {
+ VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithTest.class, "invoke_V", MethodType.genericMethodType(0, true));
+ } catch (ReflectiveOperationException ex) {
+ throw uncaughtException(ex);
+ }
+ }
+ }
+
+ static
+ MethodHandle makeGuardWithTest(MethodHandle test,
+ MethodHandle target,
+ MethodHandle fallback) {
+ return GuardWithTest.make(test, target, fallback);
+ }
+
+ private static class GuardWithCatch extends BoundMethodHandle {
+ private final MethodHandle target;
+ private final Class extends Throwable> exType;
+ private final MethodHandle catcher;
+ GuardWithCatch(MethodHandle target, Class extends Throwable> exType, MethodHandle catcher) {
+ this(INVOKES[target.type().parameterCount()], target, exType, catcher);
+ }
+ GuardWithCatch(MethodHandle invoker,
+ MethodHandle target, Class extends Throwable> exType, MethodHandle catcher) {
+ super(invoker);
+ this.target = target;
+ this.exType = exType;
+ this.catcher = catcher;
+ }
+ @Override
+ public String toString() {
+ return addTypeString(target, this);
+ }
+ private Object invoke_V(Object... av) throws Throwable {
+ try {
+ return target.invokeExact(av);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, av);
+ }
+ }
+ private Object invoke_L0() throws Throwable {
+ try {
+ return target.invokeExact();
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t);
+ }
+ }
+ private Object invoke_L1(Object a0) throws Throwable {
+ try {
+ return target.invokeExact(a0);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, a0);
+ }
+ }
+ private Object invoke_L2(Object a0, Object a1) throws Throwable {
+ try {
+ return target.invokeExact(a0, a1);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, a0, a1);
+ }
+ }
+ private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
+ try {
+ return target.invokeExact(a0, a1, a2);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, a0, a1, a2);
+ }
+ }
+ private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
+ try {
+ return target.invokeExact(a0, a1, a2, a3);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, a0, a1, a2, a3);
+ }
+ }
+ private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
+ try {
+ return target.invokeExact(a0, a1, a2, a3, a4);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, a0, a1, a2, a3, a4);
+ }
+ }
+ private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
+ try {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5);
+ }
+ }
+ private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
+ try {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6);
+ }
+ }
+ private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
+ try {
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7);
+ } catch (Throwable t) {
+ if (!exType.isInstance(t)) throw t;
+ return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6, a7);
+ }
+ }
+ static MethodHandle[] makeInvokes() {
+ ArrayList invokes = new ArrayList();
+ MethodHandles.Lookup lookup = IMPL_LOOKUP;
+ for (;;) {
+ int nargs = invokes.size();
+ String name = "invoke_L"+nargs;
+ MethodHandle invoke = null;
+ try {
+ invoke = lookup.findVirtual(GuardWithCatch.class, name, MethodType.genericMethodType(nargs));
+ } catch (ReflectiveOperationException ex) {
+ }
+ if (invoke == null) break;
+ invokes.add(invoke);
+ }
+ assert(invokes.size() == 9); // current number of methods
+ return invokes.toArray(new MethodHandle[0]);
+ };
+ static final MethodHandle[] INVOKES = makeInvokes();
+ // For testing use this:
+ //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
+ static final MethodHandle VARARGS_INVOKE;
+ static {
+ try {
+ VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithCatch.class, "invoke_V", MethodType.genericMethodType(0, true));
+ } catch (ReflectiveOperationException ex) {
+ throw uncaughtException(ex);
+ }
+ }
+ }
+
+
+ static
+ MethodHandle makeGuardWithCatch(MethodHandle target,
+ Class extends Throwable> exType,
+ MethodHandle catcher) {
+ MethodType type = target.type();
+ MethodType ctype = catcher.type();
+ int nargs = type.parameterCount();
+ if (nargs < GuardWithCatch.INVOKES.length) {
+ MethodType gtype = type.generic();
+ MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
+ MethodHandle gtarget = convertArguments(target, gtype, type, null);
+ MethodHandle gcatcher = convertArguments(catcher, gcatchType, ctype, null);
+ MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher);
+ if (gtarget == null || gcatcher == null || gguard == null) return null;
+ return convertArguments(gguard, type, gtype, null);
+ } else {
+ MethodType gtype = MethodType.genericMethodType(0, true);
+ MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
+ MethodHandle gtarget = spreadArguments(target, gtype, 0);
+ MethodHandle gcatcher = spreadArguments(catcher, gcatchType, 1);
+ MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher);
+ if (gtarget == null || gcatcher == null || gguard == null) return null;
+ return collectArguments(gguard, type, 0, null);
+ }
+ }
+
+ static
+ MethodHandle throwException(MethodType type) {
+ return AdapterMethodHandle.makeRetypeRaw(type, throwException());
+ }
+
+ static MethodHandle THROW_EXCEPTION;
+ static MethodHandle throwException() {
+ if (THROW_EXCEPTION != null) return THROW_EXCEPTION;
+ try {
+ THROW_EXCEPTION
+ = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
+ MethodType.methodType(Empty.class, Throwable.class));
+ } catch (ReflectiveOperationException ex) {
+ throw new RuntimeException(ex);
+ }
+ return THROW_EXCEPTION;
+ }
+ static Empty throwException(T t) throws T { throw t; }
+
+ // Linkage support:
+ static void registerBootstrap(Class> callerClass, MethodHandle bootstrapMethod) {
+ MethodHandleNatives.registerBootstrap(callerClass, bootstrapMethod);
+ }
+ static MethodHandle getBootstrap(Class> callerClass) {
+ return MethodHandleNatives.getBootstrap(callerClass);
+ }
+
+ static MethodHandle asVarargsCollector(MethodHandle target, Class> arrayType) {
+ return AdapterMethodHandle.makeVarargsCollector(target, arrayType);
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * The JVM interface for the method handles package is all here.
+ * This is an interface internal and private to an implemetantion of JSR 292.
+ * This class is not part of the JSR 292 standard.
+ * @author jrose
+ */
+class MethodHandleNatives {
+
+ private MethodHandleNatives() { } // static only
+
+ /// MethodName support
+
+ static native void init(MemberName self, Object ref);
+ static native void expand(MemberName self);
+ static native void resolve(MemberName self, Class> caller);
+ static native int getMembers(Class> defc, String matchName, String matchSig,
+ int matchFlags, Class> caller, int skip, MemberName[] results);
+
+ /// MethodHandle support
+
+ /** Initialize the method handle to adapt the call. */
+ static native void init(AdapterMethodHandle self, MethodHandle target, int argnum);
+ /** Initialize the method handle to call the correct method, directly. */
+ static native void init(BoundMethodHandle self, Object target, int argnum);
+ /** Initialize the method handle to call as if by an invoke* instruction. */
+ static native void init(DirectMethodHandle self, Object ref, boolean doDispatch, Class> caller);
+
+ /** Initialize a method type, once per form. */
+ static native void init(MethodType self);
+
+ /** Tell the JVM about a class's bootstrap method. */
+ static native void registerBootstrap(Class> caller, MethodHandle bootstrapMethod);
+
+ /** Ask the JVM about a class's bootstrap method. */
+ static native MethodHandle getBootstrap(Class> caller);
+
+ /** Tell the JVM that we need to change the target of an invokedynamic. */
+ static native void setCallSiteTarget(CallSite site, MethodHandle target);
+
+ /** Fetch the vmtarget field.
+ * It will be sanitized as necessary to avoid exposing non-Java references.
+ * This routine is for debugging and reflection.
+ */
+ static native Object getTarget(MethodHandle self, int format);
+
+ /** Fetch the name of the handled method, if available.
+ * This routine is for debugging and reflection.
+ */
+ static MemberName getMethodName(MethodHandle self) {
+ return (MemberName) getTarget(self, ETF_METHOD_NAME);
+ }
+
+ /** Fetch the reflective version of the handled method, if available.
+ */
+ static AccessibleObject getTargetMethod(MethodHandle self) {
+ return (AccessibleObject) getTarget(self, ETF_REFLECT_METHOD);
+ }
+
+ /** Fetch the target of this method handle.
+ * If it directly targets a method, return a MemberName for the method.
+ * If it is chained to another method handle, return that handle.
+ */
+ static Object getTargetInfo(MethodHandle self) {
+ return getTarget(self, ETF_HANDLE_OR_METHOD_NAME);
+ }
+
+ static Object[] makeTarget(Class> defc, String name, String sig, int mods, Class> refc) {
+ return new Object[] { defc, name, sig, mods, refc };
+ }
+
+ /** Fetch MH-related JVM parameter.
+ * which=0 retrieves MethodHandlePushLimit
+ * which=1 retrieves stack slot push size (in address units)
+ */
+ static native int getConstant(int which);
+
+ /** Java copy of MethodHandlePushLimit in range 2..255. */
+ static final int JVM_PUSH_LIMIT;
+ /** JVM stack motion (in words) after one slot is pushed, usually -1.
+ */
+ static final int JVM_STACK_MOVE_UNIT;
+
+ /** Which conv-ops are implemented by the JVM? */
+ static final int CONV_OP_IMPLEMENTED_MASK;
+
+ private static native void registerNatives();
+ static {
+ int JVM_PUSH_LIMIT_;
+ int JVM_STACK_MOVE_UNIT_;
+ int CONV_OP_IMPLEMENTED_MASK_;
+ try {
+ registerNatives();
+ JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT);
+ JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT);
+ CONV_OP_IMPLEMENTED_MASK_ = getConstant(Constants.GC_CONV_OP_IMPLEMENTED_MASK);
+ //sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
+ } catch (UnsatisfiedLinkError ee) {
+ // ignore; if we use init() methods later we'll see linkage errors
+ JVM_PUSH_LIMIT_ = 3; // arbitrary
+ JVM_STACK_MOVE_UNIT_ = -1; // arbitrary
+ CONV_OP_IMPLEMENTED_MASK_ = 0;
+ JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_;
+ JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_;
+ throw ee; // just die; hopeless to try to run with an older JVM
+ }
+ JVM_PUSH_LIMIT = JVM_PUSH_LIMIT_;
+ JVM_STACK_MOVE_UNIT = JVM_STACK_MOVE_UNIT_;
+ if (CONV_OP_IMPLEMENTED_MASK_ == 0)
+ CONV_OP_IMPLEMENTED_MASK_ = DEFAULT_CONV_OP_IMPLEMENTED_MASK;
+ CONV_OP_IMPLEMENTED_MASK = CONV_OP_IMPLEMENTED_MASK_;
+ }
+
+ // All compile-time constants go here.
+ // There is an opportunity to check them against the JVM's idea of them.
+ static class Constants {
+ Constants() { } // static only
+ // MethodHandleImpl
+ static final int // for getConstant
+ GC_JVM_PUSH_LIMIT = 0,
+ GC_JVM_STACK_MOVE_UNIT = 1,
+ GC_CONV_OP_IMPLEMENTED_MASK = 2;
+ static final int
+ ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
+ ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self)
+ ETF_METHOD_NAME = 2, // ultimate method as MemberName
+ ETF_REFLECT_METHOD = 3; // ultimate method as java.lang.reflect object (sans refClass)
+
+ // MemberName
+ // The JVM uses values of -2 and above for vtable indexes.
+ // Field values are simple positive offsets.
+ // Ref: src/share/vm/oops/methodOop.hpp
+ // This value is negative enough to avoid such numbers,
+ // but not too negative.
+ static final int
+ MN_IS_METHOD = 0x00010000, // method (not constructor)
+ MN_IS_CONSTRUCTOR = 0x00020000, // constructor
+ MN_IS_FIELD = 0x00040000, // field
+ MN_IS_TYPE = 0x00080000, // nested type
+ MN_SEARCH_SUPERCLASSES = 0x00100000, // for MHN.getMembers
+ MN_SEARCH_INTERFACES = 0x00200000, // for MHN.getMembers
+ VM_INDEX_UNINITIALIZED = -99;
+
+ // BoundMethodHandle
+ /** Constants for decoding the vmargslot field, which contains 2 values. */
+ static final int
+ ARG_SLOT_PUSH_SHIFT = 16,
+ ARG_SLOT_MASK = (1< rtype, Class>[] ptypes) {
+ return MethodType.makeImpl(rtype, ptypes, true);
+ }
+
+ /**
+ * The JVM wants to use a MethodType with invokeGeneric. Give the runtime fair warning.
+ */
+ static void notifyGenericMethodType(MethodType type) {
+ type.form().notifyGenericMethodType();
+ }
+
+ /**
+ * The JVM wants to raise an exception. Here's the path.
+ */
+ static void raiseException(int code, Object actual, Object required) {
+ String message;
+ // disregard the identity of the actual object, if it is not a class:
+ if (!(actual instanceof Class) && !(actual instanceof MethodType))
+ actual = actual.getClass();
+ if (actual != null)
+ message = "required "+required+" but encountered "+actual;
+ else
+ message = "required "+required;
+ switch (code) {
+ case 192: // checkcast
+ throw new ClassCastException(message);
+ default:
+ throw new InternalError("unexpected code "+code+": "+message);
+ }
+ }
+
+ /**
+ * The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
+ * It will make an up-call to this method. (Do not change the name or signature.)
+ */
+ static MethodHandle linkMethodHandleConstant(Class> callerClass, int refKind,
+ Class> defc, String name, Object type) {
+ try {
+ Lookup lookup = IMPL_LOOKUP.in(callerClass);
+ switch (refKind) {
+ case REF_getField: return lookup.findGetter( defc, name, (Class>) type );
+ case REF_getStatic: return lookup.findStaticGetter( defc, name, (Class>) type );
+ case REF_putField: return lookup.findSetter( defc, name, (Class>) type );
+ case REF_putStatic: return lookup.findStaticSetter( defc, name, (Class>) type );
+ case REF_invokeVirtual: return lookup.findVirtual( defc, name, (MethodType) type );
+ case REF_invokeStatic: return lookup.findStatic( defc, name, (MethodType) type );
+ case REF_invokeSpecial: return lookup.findSpecial( defc, name, (MethodType) type, callerClass );
+ case REF_newInvokeSpecial: return lookup.findConstructor( defc, (MethodType) type );
+ case REF_invokeInterface: return lookup.findVirtual( defc, name, (MethodType) type );
+ }
+ throw new IllegalArgumentException("bad MethodHandle constant "+name+" : "+type);
+ } catch (ReflectiveOperationException ex) {
+ Error err = new IncompatibleClassChangeError();
+ err.initCause(ex);
+ throw err;
+ }
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+package java.lang.invoke;
+
+/**
+ * This class consists exclusively of static names internal to the
+ * method handle implementation.
+ * Usage: {@code import static java.lang.invoke.MethodHandleStatics.*}
+ * @author John Rose, JSR 292 EG
+ */
+/*non-public*/ class MethodHandleStatics {
+
+ private MethodHandleStatics() { } // do not instantiate
+
+ /*non-public*/ static String getNameString(MethodHandle target, MethodType type) {
+ if (type == null)
+ type = target.type();
+ MemberName name = null;
+ if (target != null)
+ name = MethodHandleNatives.getMethodName(target);
+ if (name == null)
+ return "invoke" + type;
+ return name.getName() + type;
+ }
+
+ /*non-public*/ static String getNameString(MethodHandle target, MethodHandle typeHolder) {
+ return getNameString(target, typeHolder == null ? (MethodType) null : typeHolder.type());
+ }
+
+ /*non-public*/ static String getNameString(MethodHandle target) {
+ return getNameString(target, (MethodType) null);
+ }
+
+ /*non-public*/ static String addTypeString(Object obj, MethodHandle target) {
+ String str = String.valueOf(obj);
+ if (target == null) return str;
+ int paren = str.indexOf('(');
+ if (paren >= 0) str = str.substring(0, paren);
+ return str + target.type();
+ }
+
+ static void checkSpreadArgument(Object av, int n) {
+ if (av == null ? n != 0 : ((Object[])av).length != n)
+ throw newIllegalArgumentException("Array is not of length "+n);
+ }
+
+ // handy shared exception makers (they simplify the common case code)
+ /*non-public*/ static RuntimeException newIllegalStateException(String message) {
+ return new IllegalStateException(message);
+ }
+ /*non-public*/ static RuntimeException newIllegalStateException(String message, Object obj) {
+ return new IllegalStateException(message(message, obj));
+ }
+ /*non-public*/ static RuntimeException newIllegalArgumentException(String message) {
+ return new IllegalArgumentException(message);
+ }
+ /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj) {
+ return new IllegalArgumentException(message(message, obj));
+ }
+ /*non-public*/ static Error uncaughtException(Exception ex) {
+ Error err = new InternalError("uncaught exception");
+ err.initCause(ex);
+ return err;
+ }
+ private static String message(String message, Object obj) {
+ if (obj != null) message = message + ": " + obj;
+ return message;
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MethodHandles.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,2357 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.*;
+import sun.invoke.WrapperInstance;
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.VerifyAccess;
+import sun.invoke.util.Wrapper;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import sun.reflect.Reflection;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * This class consists exclusively of static methods that operate on or return
+ * method handles. They fall into several categories:
+ *
+ * Lookup methods which help create method handles for methods and fields.
+ * Combinator methods, which combine or transform pre-existing method handles into new ones.
+ * Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
+ * Wrapper methods which can convert between method handles and interface types.
+ *
+ *
+ * @author John Rose, JSR 292 EG
+ */
+public class MethodHandles {
+
+ private MethodHandles() { } // do not instantiate
+
+ private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+ static { MethodHandleImpl.initStatics(); }
+ // See IMPL_LOOKUP below.
+
+ //// Method handle creation from ordinary methods.
+
+ /**
+ * Returns a {@link Lookup lookup object} on the caller,
+ * which has the capability to access any method handle that the caller has access to,
+ * including direct method handles to private fields and methods.
+ * This lookup object is a capability which may be delegated to trusted agents.
+ * Do not store it in place where untrusted code can access it.
+ */
+ public static Lookup lookup() {
+ return new Lookup();
+ }
+
+ /**
+ * Returns a {@link Lookup lookup object} which is trusted minimally.
+ * It can only be used to create method handles to
+ * publicly accessible fields and methods.
+ *
+ * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
+ * of this lookup object will be {@link java.lang.Object}.
+ *
+ * The lookup class can be changed to any other class {@code C} using an expression of the form
+ * {@linkplain Lookup#in publicLookup().in(C.class)
}.
+ * Since all classes have equal access to public names,
+ * such a change would confer no new access rights.
+ */
+ public static Lookup publicLookup() {
+ return Lookup.PUBLIC_LOOKUP;
+ }
+
+ /**
+ * A lookup object is a factory for creating method handles,
+ * when the creation requires access checking.
+ * Method handles do not perform
+ * access checks when they are called, but rather when they are created.
+ * Therefore, method handle access
+ * restrictions must be enforced when a method handle is created.
+ * The caller class against which those restrictions are enforced
+ * is known as the {@linkplain #lookupClass lookup class}.
+ *
+ * A lookup class which needs to create method handles will call
+ * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
+ * When the {@code Lookup} factory object is created, the identity of the lookup class is
+ * determined, and securely stored in the {@code Lookup} object.
+ * The lookup class (or its delegates) may then use factory methods
+ * on the {@code Lookup} object to create method handles for access-checked members.
+ * This includes all methods, constructors, and fields which are allowed to the lookup class,
+ * even private ones.
+ *
+ * The factory methods on a {@code Lookup} object correspond to all major
+ * use cases for methods, constructors, and fields.
+ * Here is a summary of the correspondence between these factory methods and
+ * the behavior the resulting method handles:
+ *
+ *
+ * lookup expression member behavior
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}
+ * FT f; (T) this.f;
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}
+ * static FT f; (T) C.f;
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}
+ * FT f; this.f = x;
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}
+ * static FT f; C.f = arg;
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}
+ * T m(A*); (T) this.m(arg*);
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}
+ * static T m(A*); (T) C.m(arg*);
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}
+ * T m(A*); (T) super.m(arg*);
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}
+ * C(A*); (T) new C(arg*);
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}
+ * (static)? FT f; (FT) aField.get(thisOrNull);
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}
+ * (static)? FT f; aField.set(thisOrNull, arg);
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}
+ * (static)? T m(A*); (T) aMethod.invoke(thisOrNull, arg*);
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}
+ * C(A*); (C) aConstructor.newInstance(arg*);
+ *
+ *
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}
+ * (static)? T m(A*); (T) aMethod.invoke(thisOrNull, arg*);
+ *
+ *
+ *
+ * Here, the type {@code C} is the class or interface being searched for a member,
+ * documented as a parameter named {@code refc} in the lookup methods.
+ * The method or constructor type {@code MT} is composed from the return type {@code T}
+ * and the sequence of argument types {@code A*}.
+ * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
+ * The formal parameter {@code this} stands for the self-reference of type {@code C};
+ * if it is present, it is always the leading argument to the method handle invocation.
+ * The name {@code arg} stands for all the other method handle arguments.
+ * In the code examples for the Core Reflection API, the name {@code thisOrNull}
+ * stands for a null reference if the accessed method or field is static,
+ * and {@code this} otherwise.
+ * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
+ * for reflective objects corresponding to the given members.
+ *
+ * The equivalence between looked-up method handles and underlying
+ * class members can break down in a few ways:
+ *
+ * If {@code C} is not symbolically accessible from the lookup class's loader,
+ * the lookup can still succeed, even when there is no equivalent
+ * Java expression or bytecoded constant.
+ * Likewise, if {@code T} or {@code MT}
+ * is not symbolically accessible from the lookup class's loader,
+ * the lookup can still succeed.
+ * For example, lookups for {@code MethodHandle.invokeExact} and
+ * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
+ * If there is a security manager installed, it can forbid the lookup
+ * on various grounds (see below ).
+ * By contrast, the {@code ldc} instruction is not subject to
+ * security manager checks.
+ *
+ *
+ * Access checking
+ * Access checks are applied in the factory methods of {@code Lookup},
+ * when a method handle is created.
+ * This is a key difference from the Core Reflection API, since
+ * {@link java.lang.reflect.Method#invoke Method.invoke}
+ * performs access checking against every caller, on every call.
+ *
+ * All access checks start from a {@code Lookup} object, which
+ * compares its recorded lookup class against all requests to
+ * create method handles.
+ * A single {@code Lookup} object can be used to create any number
+ * of access-checked method handles, all checked against a single
+ * lookup class.
+ *
+ * A {@code Lookup} object can be shared with other trusted code,
+ * such as a metaobject protocol.
+ * A shared {@code Lookup} object delegates the capability
+ * to create method handles on private members of the lookup class.
+ * Even if privileged code uses the {@code Lookup} object,
+ * the access checking is confined to the privileges of the
+ * original lookup class.
+ *
+ * A lookup can fail, because
+ * the containing class is not accessible to the lookup class, or
+ * because the desired class member is missing, or because the
+ * desired class member is not accessible to the lookup class.
+ * In any of these cases, a {@code ReflectiveOperationException} will be
+ * thrown from the attempted lookup. The exact class will be one of
+ * the following:
+ *
+ * NoSuchMethodException — if a method is requested but does not exist
+ * NoSuchFieldException — if a field is requested but does not exist
+ * IllegalAccessException — if the member exists but an access check fails
+ *
+ *
+ * In general, the conditions under which a method handle may be
+ * looked up for a method {@code M} are exactly equivalent to the conditions
+ * under which the lookup class could have compiled and resolved a call to {@code M}.
+ * And the effect of invoking the method handle resulting from the lookup
+ * is exactly equivalent to executing the compiled and resolved call to {@code M}.
+ * The same point is true of fields and constructors.
+ *
+ * In some cases, access between nested classes is obtained by the Java compiler by creating
+ * an wrapper method to access a private method of another class
+ * in the same top-level declaration.
+ * For example, a nested class {@code C.D}
+ * can access private members within other related classes such as
+ * {@code C}, {@code C.D.E}, or {@code C.B},
+ * but the Java compiler may need to generate wrapper methods in
+ * those related classes. In such cases, a {@code Lookup} object on
+ * {@code C.E} would be unable to those private members.
+ * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
+ * which can transform a lookup on {@code C.E} into one on any of those other
+ * classes, without special elevation of privilege.
+ *
+ * Although bytecode instructions can only refer to classes in
+ * a related class loader, this API can search for methods in any
+ * class, as long as a reference to its {@code Class} object is
+ * available. Such cross-loader references are also possible with the
+ * Core Reflection API, and are impossible to bytecode instructions
+ * such as {@code invokestatic} or {@code getfield}.
+ * There is a {@linkplain java.lang.SecurityManager security manager API}
+ * to allow applications to check such cross-loader references.
+ * These checks apply to both the {@code MethodHandles.Lookup} API
+ * and the Core Reflection API
+ * (as found on {@link java.lang.Class Class}).
+ *
+ * Access checks only apply to named and reflected methods,
+ * constructors, and fields.
+ * Other method handle creation methods, such as
+ * {@link #convertArguments MethodHandles.convertArguments},
+ * do not require any access checks, and are done
+ * with static methods of {@link MethodHandles},
+ * independently of any {@code Lookup} object.
+ *
+ *
Security manager interactions
+ *
+ * If a security manager is present, member lookups are subject to
+ * additional checks.
+ * From one to four calls are made to the security manager.
+ * Any of these calls can refuse access by throwing a
+ * {@link java.lang.SecurityException SecurityException}.
+ * Define {@code smgr} as the security manager,
+ * {@code refc} as the containing class in which the member
+ * is being sought, and {@code defc} as the class in which the
+ * member is actually defined.
+ * The calls are made according to the following rules:
+ *
+ * In all cases, {@link SecurityManager#checkMemberAccess
+ * smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
+ * If the class loader of the lookup class is not
+ * the same as or an ancestor of the class loader of {@code refc},
+ * then {@link SecurityManager#checkPackageAccess
+ * smgr.checkPackageAccess(refcPkg)} is called,
+ * where {@code refcPkg} is the package of {@code refc}.
+ * If the retrieved member is not public,
+ * {@link SecurityManager#checkMemberAccess
+ * smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
+ * (Note that {@code defc} might be the same as {@code refc}.)
+ * If the retrieved member is not public,
+ * and if {@code defc} and {@code refc} are in different class loaders,
+ * and if the class loader of the lookup class is not
+ * the same as or an ancestor of the class loader of {@code defc},
+ * then {@link SecurityManager#checkPackageAccess
+ * smgr.checkPackageAccess(defcPkg)} is called,
+ * where {@code defcPkg} is the package of {@code defc}.
+ *
+ * In all cases, the requesting class presented to the security
+ * manager will be the lookup class from the current {@code Lookup} object.
+ */
+ public static final
+ class Lookup {
+ /** The class on behalf of whom the lookup is being performed. */
+ private final Class> lookupClass;
+
+ /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
+ private final int allowedModes;
+
+ /** A single-bit mask representing {@code public} access,
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value, {@code 0x01}, happens to be the same as the value of the
+ * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
+ */
+ public static final int PUBLIC = Modifier.PUBLIC;
+
+ /** A single-bit mask representing {@code private} access,
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value, {@code 0x02}, happens to be the same as the value of the
+ * {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
+ */
+ public static final int PRIVATE = Modifier.PRIVATE;
+
+ /** A single-bit mask representing {@code protected} access,
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value, {@code 0x04}, happens to be the same as the value of the
+ * {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
+ */
+ public static final int PROTECTED = Modifier.PROTECTED;
+
+ /** A single-bit mask representing {@code package} access (default access),
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value is {@code 0x08}, which does not correspond meaningfully to
+ * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
+ */
+ public static final int PACKAGE = Modifier.STATIC;
+
+ private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
+ private static final int TRUSTED = -1;
+
+ private static int fixmods(int mods) {
+ mods &= (ALL_MODES - PACKAGE);
+ return (mods != 0) ? mods : PACKAGE;
+ }
+
+ /** Tells which class is performing the lookup. It is this class against
+ * which checks are performed for visibility and access permissions.
+ *
+ * The class implies a maximum level of access permission,
+ * but the permissions may be additionally limited by the bitmask
+ * {@link #lookupModes lookupModes}, which controls whether non-public members
+ * can be accessed.
+ */
+ public Class> lookupClass() {
+ return lookupClass;
+ }
+
+ // This is just for calling out to MethodHandleImpl.
+ private Class> lookupClassOrNull() {
+ return (allowedModes == TRUSTED) ? null : lookupClass;
+ }
+
+ /** Tells which access-protection classes of members this lookup object can produce.
+ * The result is a bit-mask of the bits
+ * {@linkplain #PUBLIC PUBLIC (0x01)},
+ * {@linkplain #PRIVATE PRIVATE (0x02)},
+ * {@linkplain #PROTECTED PROTECTED (0x04)},
+ * and {@linkplain #PACKAGE PACKAGE (0x08)}.
+ *
+ * A freshly-created lookup object
+ * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
+ * has all possible bits set, since the caller class can access all its own members.
+ * A lookup object on a new lookup class
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
+ * may have some mode bits set to zero.
+ * The purpose of this is to restrict access via the new lookup object,
+ * so that it can access only names which can be reached by the original
+ * lookup object, and also by the new lookup class.
+ */
+ public int lookupModes() {
+ return allowedModes & ALL_MODES;
+ }
+
+ /** Embody the current class (the lookupClass) as a lookup class
+ * for method handle creation.
+ * Must be called by from a method in this package,
+ * which in turn is called by a method not in this package.
+ *
+ * Also, don't make it private, lest javac interpose
+ * an access$N method.
+ */
+ Lookup() {
+ this(getCallerClassAtEntryPoint(), ALL_MODES);
+ // make sure we haven't accidentally picked up a privileged class:
+ checkUnprivilegedlookupClass(lookupClass);
+ }
+
+ Lookup(Class> lookupClass) {
+ this(lookupClass, ALL_MODES);
+ }
+
+ private Lookup(Class> lookupClass, int allowedModes) {
+ this.lookupClass = lookupClass;
+ this.allowedModes = allowedModes;
+ }
+
+ /**
+ * Creates a lookup on the specified new lookup class.
+ * The resulting object will report the specified
+ * class as its own {@link #lookupClass lookupClass}.
+ *
+ * However, the resulting {@code Lookup} object is guaranteed
+ * to have no more access capabilities than the original.
+ * In particular, access capabilities can be lost as follows:
+ * If the new lookup class differs from the old one,
+ * protected members will not be accessible by virtue of inheritance.
+ * (Protected members may continue to be accessible because of package sharing.)
+ * If the new lookup class is in a different package
+ * than the old one, protected and default (package) members will not be accessible.
+ * If the new lookup class is not within the same package member
+ * as the old one, private members will not be accessible.
+ * If the new lookup class is not accessible to the old lookup class,
+ * then no members, not even public members, will be accessible.
+ * (In all other cases, public members will continue to be accessible.)
+ *
+ *
+ * @param requestedLookupClass the desired lookup class for the new lookup object
+ * @return a lookup object which reports the desired lookup class
+ * @throws NullPointerException if the argument is null
+ */
+ public Lookup in(Class> requestedLookupClass) {
+ requestedLookupClass.getClass(); // null check
+ if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
+ return new Lookup(requestedLookupClass, ALL_MODES);
+ if (requestedLookupClass == this.lookupClass)
+ return this; // keep same capabilities
+ int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
+ if ((newModes & PACKAGE) != 0
+ && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
+ newModes &= ~(PACKAGE|PRIVATE);
+ }
+ // Allow nestmate lookups to be created without special privilege:
+ if ((newModes & PRIVATE) != 0
+ && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
+ newModes &= ~PRIVATE;
+ }
+ if (newModes == PUBLIC
+ && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass)) {
+ // The requested class it not accessible from the lookup class.
+ // No permissions.
+ newModes = 0;
+ }
+ checkUnprivilegedlookupClass(requestedLookupClass);
+ return new Lookup(requestedLookupClass, newModes);
+ }
+
+ // Make sure outer class is initialized first.
+ static { IMPL_NAMES.getClass(); }
+
+ /** Version of lookup which is trusted minimally.
+ * It can only be used to create method handles to
+ * publicly accessible members.
+ */
+ static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
+
+ /** Package-private version of lookup which is trusted. */
+ static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
+
+ private static void checkUnprivilegedlookupClass(Class> lookupClass) {
+ String name = lookupClass.getName();
+ if (name.startsWith("java.lang.invoke."))
+ throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
+ }
+
+ /**
+ * Displays the name of the class from which lookups are to be made.
+ * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
+ * If there are restrictions on the access permitted to this lookup,
+ * this is indicated by adding a suffix to the class name, consisting
+ * of a slash and a keyword. The keyword represents the strongest
+ * allowed access, and is chosen as follows:
+ *
+ * If no access is allowed, the suffix is "/noaccess".
+ * If only public access is allowed, the suffix is "/public".
+ * If only public and package access are allowed, the suffix is "/package".
+ * If only public, package, and private access are allowed, the suffix is "/private".
+ *
+ * If none of the above cases apply, it is the case that full
+ * access (public, package, private, and protected) is allowed.
+ * In this case, no suffix is added.
+ * This is true only of an object obtained originally from
+ * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
+ * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
+ * always have restricted access, and will display a suffix.
+ *
+ * (It may seem strange that protected access should be
+ * stronger than private access. Viewed independently from
+ * package access, protected access is the first to be lost,
+ * because it requires a direct subclass relationship between
+ * caller and callee.)
+ * @see #in
+ */
+ @Override
+ public String toString() {
+ String cname = lookupClass.getName();
+ switch (allowedModes) {
+ case 0: // no privileges
+ return cname + "/noaccess";
+ case PUBLIC:
+ return cname + "/public";
+ case PUBLIC|PACKAGE:
+ return cname + "/package";
+ case ALL_MODES & ~PROTECTED:
+ return cname + "/private";
+ case ALL_MODES:
+ return cname;
+ case TRUSTED:
+ return "/trusted"; // internal only; not exported
+ default: // Should not happen, but it's a bitfield...
+ cname = cname + "/" + Integer.toHexString(allowedModes);
+ assert(false) : cname;
+ return cname;
+ }
+ }
+
+ // call this from an entry point method in Lookup with extraFrames=0.
+ private static Class> getCallerClassAtEntryPoint() {
+ final int CALLER_DEPTH = 4;
+ // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
+ // 2: Lookup., 3: MethodHandles.*, 4: caller
+ // Note: This should be the only use of getCallerClass in this file.
+ assert(Reflection.getCallerClass(CALLER_DEPTH-1) == MethodHandles.class);
+ return Reflection.getCallerClass(CALLER_DEPTH);
+ }
+
+ /**
+ * Produces a method handle for a static method.
+ * The type of the method handle will be that of the method.
+ * (Since static methods do not take receivers, there is no
+ * additional receiver argument inserted into the method handle type,
+ * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
+ * The method and all its argument types must be accessible to the lookup class.
+ * If the method's class has not yet been initialized, that is done
+ * immediately, before the method handle is returned.
+ *
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * @param refc the class from which the method is accessed
+ * @param name the name of the method
+ * @param type the type of the method
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws IllegalAccessException if access checking fails, or if the method is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public
+ MethodHandle findStatic(Class> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ MemberName method = resolveOrFail(refc, name, type, true);
+ checkMethod(refc, method, true);
+ return MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
+ }
+
+ /**
+ * Produces a method handle for a virtual method.
+ * The type of the method handle will be that of the method,
+ * with the receiver type (usually {@code refc}) prepended.
+ * The method and all its argument types must be accessible to the lookup class.
+ *
+ * When called, the handle will treat the first argument as a receiver
+ * and dispatch on the receiver's type to determine which method
+ * implementation to enter.
+ * (The dispatching action is identical with that performed by an
+ * {@code invokevirtual} or {@code invokeinterface} instruction.)
+ *
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ *
+ * Because of the general equivalence between {@code invokevirtual}
+ * instructions and method handles produced by {@code findVirtual},
+ * if the class is {@code MethodHandle} and the name string is
+ * {@code invokeExact} or {@code invokeGeneric}, the resulting
+ * method handle is equivalent to one produced by
+ * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
+ * {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}
+ * with the same {@code type} argument.
+ *
+ * @param refc the class or interface from which the method is accessed
+ * @param name the name of the method
+ * @param type the type of the method, with the receiver argument omitted
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws IllegalAccessException if access checking fails, or if the method is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findVirtual(Class> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ MemberName method = resolveOrFail(refc, name, type, false);
+ checkMethod(refc, method, false);
+ MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
+ return restrictProtectedReceiver(method, mh);
+ }
+
+ /**
+ * Produces a method handle which creates an object and initializes it, using
+ * the constructor of the specified type.
+ * The parameter types of the method handle will be those of the constructor,
+ * while the return type will be a reference to the constructor's class.
+ * The constructor and all its argument types must be accessible to the lookup class.
+ * If the constructor's class has not yet been initialized, that is done
+ * immediately, before the method handle is returned.
+ *
+ * Note: The requested type must have a return type of {@code void}.
+ * This is consistent with the JVM's treatment of constructor type descriptors.
+ *
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
+ * @param refc the class or interface from which the method is accessed
+ * @param type the type of the method, with the receiver argument omitted, and a void return type
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the constructor does not exist
+ * @throws IllegalAccessException if access checking fails
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findConstructor(Class> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ String name = "";
+ MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
+ assert(ctor.isConstructor());
+ checkAccess(refc, ctor);
+ MethodHandle rawMH = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
+ MethodHandle allocMH = MethodHandleImpl.makeAllocator(rawMH);
+ return fixVarargs(allocMH, rawMH);
+ }
+
+ /** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
+ private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
+ boolean va1 = mh.isVarargsCollector();
+ boolean va2 = matchMH.isVarargsCollector();
+ if (va1 == va2) {
+ return mh;
+ } else if (va2) {
+ MethodType type = mh.type();
+ int arity = type.parameterCount();
+ return mh.asVarargsCollector(type.parameterType(arity-1));
+ } else {
+ throw new InternalError("already varargs, but template is not: "+mh);
+ }
+ }
+
+ /**
+ * Produces an early-bound method handle for a virtual method,
+ * as if called from an {@code invokespecial}
+ * instruction from {@code caller}.
+ * The type of the method handle will be that of the method,
+ * with a suitably restricted receiver type (such as {@code caller}) prepended.
+ * The method and all its argument types must be accessible
+ * to the caller.
+ *
+ * When called, the handle will treat the first argument as a receiver,
+ * but will not dispatch on the receiver's type.
+ * (This direct invocation action is identical with that performed by an
+ * {@code invokespecial} instruction.)
+ *
+ * If the explicitly specified caller class is not identical with the
+ * lookup class, or if this lookup object does not have private access
+ * privileges, the access fails.
+ *
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the name of the method (which must not be "<init>")
+ * @param type the type of the method, with the receiver argument omitted
+ * @param specialCaller the proposed calling class to perform the {@code invokespecial}
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws IllegalAccessException if access checking fails
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findSpecial(Class> refc, String name, MethodType type,
+ Class> specialCaller) throws NoSuchMethodException, IllegalAccessException {
+ checkSpecialCaller(specialCaller);
+ MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
+ checkMethod(refc, method, false);
+ MethodHandle mh = MethodHandleImpl.findMethod(method, false, specialCaller);
+ return restrictReceiver(method, mh, specialCaller);
+ }
+
+ /**
+ * Produces a method handle giving read access to a non-static field.
+ * The type of the method handle will have a return type of the field's
+ * value type.
+ * The method handle's single argument will be the instance containing
+ * the field.
+ * Access checking is performed immediately on behalf of the lookup class.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the field's name
+ * @param type the field's type
+ * @return a method handle which can load values from the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findGetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
+ return makeAccessor(refc, name, type, false, false);
+ }
+
+ /**
+ * Produces a method handle giving write access to a non-static field.
+ * The type of the method handle will have a void return type.
+ * The method handle will take two arguments, the instance containing
+ * the field, and the value to be stored.
+ * The second argument will be of the field's value type.
+ * Access checking is performed immediately on behalf of the lookup class.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the field's name
+ * @param type the field's type
+ * @return a method handle which can store values into the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findSetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
+ return makeAccessor(refc, name, type, false, true);
+ }
+
+ /**
+ * Produces a method handle giving read access to a static field.
+ * The type of the method handle will have a return type of the field's
+ * value type.
+ * The method handle will take no arguments.
+ * Access checking is performed immediately on behalf of the lookup class.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the field's name
+ * @param type the field's type
+ * @return a method handle which can load values from the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findStaticGetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
+ return makeAccessor(refc, name, type, true, false);
+ }
+
+ /**
+ * Produces a method handle giving write access to a static field.
+ * The type of the method handle will have a void return type.
+ * The method handle will take a single
+ * argument, of the field's value type, the value to be stored.
+ * Access checking is performed immediately on behalf of the lookup class.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the field's name
+ * @param type the field's type
+ * @return a method handle which can store values into the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findStaticSetter(Class> refc, String name, Class> type) throws NoSuchFieldException, IllegalAccessException {
+ return makeAccessor(refc, name, type, true, true);
+ }
+
+ /**
+ * Produces an early-bound method handle for a non-static method.
+ * The receiver must have a supertype {@code defc} in which a method
+ * of the given name and type is accessible to the lookup class.
+ * The method and all its argument types must be accessible to the lookup class.
+ * The type of the method handle will be that of the method,
+ * without any insertion of an additional receiver parameter.
+ * The given receiver will be bound into the method handle,
+ * so that every call to the method handle will invoke the
+ * requested method on the given receiver.
+ *
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set
+ * and the trailing array argument is not the only argument.
+ * (If the trailing array argument is the only argument,
+ * the given receiver value will be bound to it.)
+ *
+ * This is equivalent to the following code:
+ *
+MethodHandle mh0 = {@link #findVirtual findVirtual}(defc, name, type);
+MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
+MethodType mt1 = mh1.type();
+if (mh0.isVarargsCollector() && mt1.parameterCount() > 0) {
+ mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
+return mh1;
+ *
+ * where {@code defc} is either {@code receiver.getClass()} or a super
+ * type of that class, in which the requested method is accessible
+ * to the lookup class.
+ * (Note that {@code bindTo} does not preserve variable arity.)
+ * @param receiver the object from which the method is accessed
+ * @param name the name of the method
+ * @param type the type of the method, with the receiver argument omitted
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws IllegalAccessException if access checking fails
+ * @exception SecurityException if a security manager is present and it
+ * refuses access
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ Class extends Object> refc = receiver.getClass(); // may get NPE
+ MemberName method = resolveOrFail(refc, name, type, false);
+ checkMethod(refc, method, false);
+ MethodHandle dmh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
+ MethodHandle bmh = MethodHandleImpl.bindReceiver(dmh, receiver);
+ if (bmh == null)
+ throw method.makeAccessException("no access", this);
+ if (dmh.type().parameterCount() == 0)
+ return dmh; // bound the trailing parameter; no varargs possible
+ return fixVarargs(bmh, dmh);
+ }
+
+ /**
+ * Makes a direct method handle to m , if the lookup class has permission.
+ * If m is non-static, the receiver argument is treated as an initial argument.
+ * If m is virtual, overriding is respected on every call.
+ * Unlike the Core Reflection API, exceptions are not wrapped.
+ * The type of the method handle will be that of the method,
+ * with the receiver type prepended (but only if it is non-static).
+ * If the method's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class.
+ * If m is not public, do not share the resulting handle with untrusted parties.
+ *
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * @param m the reflected method
+ * @return a method handle which can invoke the reflected method
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ */
+ public MethodHandle unreflect(Method m) throws IllegalAccessException {
+ MemberName method = new MemberName(m);
+ assert(method.isMethod());
+ if (!m.isAccessible()) checkMethod(method.getDeclaringClass(), method, method.isStatic());
+ MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
+ if (!m.isAccessible()) mh = restrictProtectedReceiver(method, mh);
+ return mh;
+ }
+
+ /**
+ * Produces a method handle for a reflected method.
+ * It will bypass checks for overriding methods on the receiver,
+ * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
+ * The type of the method handle will be that of the method,
+ * with the special caller type prepended (and not the receiver of the method).
+ * If the method's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class,
+ * as if {@code invokespecial} instruction were being linked.
+ *
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * @param m the reflected method
+ * @param specialCaller the class nominally calling the method
+ * @return a method handle which can invoke the reflected method
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle unreflectSpecial(Method m, Class> specialCaller) throws IllegalAccessException {
+ checkSpecialCaller(specialCaller);
+ MemberName method = new MemberName(m);
+ assert(method.isMethod());
+ // ignore m.isAccessible: this is a new kind of access
+ checkMethod(m.getDeclaringClass(), method, false);
+ MethodHandle mh = MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
+ return restrictReceiver(method, mh, specialCaller);
+ }
+
+ /**
+ * Produces a method handle for a reflected constructor.
+ * The type of the method handle will be that of the constructor,
+ * with the return type changed to the declaring class.
+ * The method handle will perform a {@code newInstance} operation,
+ * creating a new instance of the constructor's class on the
+ * arguments passed to the method handle.
+ *
+ * If the constructor's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class.
+ *
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
+ * @param c the reflected constructor
+ * @return a method handle which can invoke the reflected constructor
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ */
+ public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
+ MemberName ctor = new MemberName(c);
+ assert(ctor.isConstructor());
+ if (!c.isAccessible()) checkAccess(c.getDeclaringClass(), ctor);
+ MethodHandle rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
+ MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
+ return fixVarargs(allocator, rawCtor);
+ }
+
+ /**
+ * Produces a method handle giving read access to a reflected field.
+ * The type of the method handle will have a return type of the field's
+ * value type.
+ * If the field is static, the method handle will take no arguments.
+ * Otherwise, its single argument will be the instance containing
+ * the field.
+ * If the field's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class.
+ * @param f the reflected field
+ * @return a method handle which can load values from the reflected field
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ */
+ public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
+ return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false);
+ }
+
+ /**
+ * Produces a method handle giving write access to a reflected field.
+ * The type of the method handle will have a void return type.
+ * If the field is static, the method handle will take a single
+ * argument, of the field's value type, the value to be stored.
+ * Otherwise, the two arguments will be the instance containing
+ * the field, and the value to be stored.
+ * If the field's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class.
+ * @param f the reflected field
+ * @return a method handle which can store values into the reflected field
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ */
+ public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
+ return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true);
+ }
+
+ /// Helper methods, all package-private.
+
+ MemberName resolveOrFail(Class> refc, String name, Class> type, boolean isStatic) throws NoSuchFieldException, IllegalAccessException {
+ checkSymbolicClass(refc); // do this before attempting to resolve
+ name.getClass(); type.getClass(); // NPE
+ int mods = (isStatic ? Modifier.STATIC : 0);
+ return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
+ NoSuchFieldException.class);
+ }
+
+ MemberName resolveOrFail(Class> refc, String name, MethodType type, boolean isStatic) throws NoSuchMethodException, IllegalAccessException {
+ checkSymbolicClass(refc); // do this before attempting to resolve
+ name.getClass(); type.getClass(); // NPE
+ int mods = (isStatic ? Modifier.STATIC : 0);
+ return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
+ NoSuchMethodException.class);
+ }
+
+ MemberName resolveOrFail(Class> refc, String name, MethodType type, boolean isStatic,
+ boolean searchSupers, Class> specialCaller) throws NoSuchMethodException, IllegalAccessException {
+ checkSymbolicClass(refc); // do this before attempting to resolve
+ name.getClass(); type.getClass(); // NPE
+ int mods = (isStatic ? Modifier.STATIC : 0);
+ return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller,
+ NoSuchMethodException.class);
+ }
+
+ void checkSymbolicClass(Class> refc) throws IllegalAccessException {
+ Class> caller = lookupClassOrNull();
+ if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
+ throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this);
+ }
+
+ void checkMethod(Class> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
+ String message;
+ if (m.isConstructor())
+ message = "expected a method, not a constructor";
+ else if (!m.isMethod())
+ message = "expected a method";
+ else if (wantStatic != m.isStatic())
+ message = wantStatic ? "expected a static method" : "expected a non-static method";
+ else
+ { checkAccess(refc, m); return; }
+ throw m.makeAccessException(message, this);
+ }
+
+ void checkAccess(Class> refc, MemberName m) throws IllegalAccessException {
+ int allowedModes = this.allowedModes;
+ if (allowedModes == TRUSTED) return;
+ int mods = m.getModifiers();
+ if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
+ return; // common case
+ int requestedModes = fixmods(mods); // adjust 0 => PACKAGE
+ if ((requestedModes & allowedModes) != 0
+ && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
+ mods, lookupClass()))
+ return;
+ if (((requestedModes & ~allowedModes) & PROTECTED) != 0
+ && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
+ // Protected members can also be checked as if they were package-private.
+ return;
+ throw m.makeAccessException(accessFailedMessage(refc, m), this);
+ }
+
+ String accessFailedMessage(Class> refc, MemberName m) {
+ Class> defc = m.getDeclaringClass();
+ int mods = m.getModifiers();
+ // check the class first:
+ boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
+ (defc == refc ||
+ Modifier.isPublic(refc.getModifiers())));
+ if (!classOK && (allowedModes & PACKAGE) != 0) {
+ classOK = (VerifyAccess.isClassAccessible(defc, lookupClass()) &&
+ (defc == refc ||
+ VerifyAccess.isClassAccessible(refc, lookupClass())));
+ }
+ if (!classOK)
+ return "class is not public";
+ if (Modifier.isPublic(mods))
+ return "access to public member failed"; // (how?)
+ if (Modifier.isPrivate(mods))
+ return "member is private";
+ if (Modifier.isProtected(mods))
+ return "member is protected";
+ return "member is private to package";
+ }
+
+ private static final boolean ALLOW_NESTMATE_ACCESS = false;
+
+ void checkSpecialCaller(Class> specialCaller) throws IllegalAccessException {
+ if (allowedModes == TRUSTED) return;
+ if ((allowedModes & PRIVATE) == 0
+ || (specialCaller != lookupClass()
+ && !(ALLOW_NESTMATE_ACCESS &&
+ VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
+ throw new MemberName(specialCaller).
+ makeAccessException("no private access for invokespecial", this);
+ }
+
+ MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
+ // The accessing class only has the right to use a protected member
+ // on itself or a subclass. Enforce that restriction, from JVMS 5.4.4, etc.
+ if (!method.isProtected() || method.isStatic()
+ || allowedModes == TRUSTED
+ || method.getDeclaringClass() == lookupClass()
+ || (ALLOW_NESTMATE_ACCESS &&
+ VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
+ return mh;
+ else
+ return restrictReceiver(method, mh, lookupClass());
+ }
+ MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class> caller) throws IllegalAccessException {
+ assert(!method.isStatic());
+ Class> defc = method.getDeclaringClass(); // receiver type of mh is too wide
+ if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
+ throw method.makeAccessException("caller class must be a subclass below the method", caller);
+ }
+ MethodType rawType = mh.type();
+ if (rawType.parameterType(0) == caller) return mh;
+ MethodType narrowType = rawType.changeParameterType(0, caller);
+ MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, null);
+ return fixVarargs(narrowMH, mh);
+ }
+
+ MethodHandle makeAccessor(Class> refc, String name, Class> type,
+ boolean isStatic, boolean isSetter) throws NoSuchFieldException, IllegalAccessException {
+ MemberName field = resolveOrFail(refc, name, type, isStatic);
+ if (isStatic != field.isStatic())
+ throw field.makeAccessException(isStatic
+ ? "expected a static field"
+ : "expected a non-static field", this);
+ return makeAccessor(refc, field, false, isSetter);
+ }
+
+ MethodHandle makeAccessor(Class> refc, MemberName field,
+ boolean trusted, boolean isSetter) throws IllegalAccessException {
+ assert(field.isField());
+ if (trusted)
+ return MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
+ checkAccess(refc, field);
+ MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
+ return restrictProtectedReceiver(field, mh);
+ }
+ }
+
+ /**
+ * Produces a method handle giving read access to elements of an array.
+ * The type of the method handle will have a return type of the array's
+ * element type. Its first argument will be the array type,
+ * and the second will be {@code int}.
+ * @param arrayClass an array type
+ * @return a method handle which can load values from the given array type
+ * @throws NullPointerException if the argument is null
+ * @throws IllegalArgumentException if arrayClass is not an array type
+ */
+ public static
+ MethodHandle arrayElementGetter(Class> arrayClass) throws IllegalArgumentException {
+ return MethodHandleImpl.accessArrayElement(arrayClass, false);
+ }
+
+ /**
+ * Produces a method handle giving write access to elements of an array.
+ * The type of the method handle will have a void return type.
+ * Its last argument will be the array's element type.
+ * The first and second arguments will be the array type and int.
+ * @return a method handle which can store values into the array type
+ * @throws NullPointerException if the argument is null
+ * @throws IllegalArgumentException if arrayClass is not an array type
+ */
+ public static
+ MethodHandle arrayElementSetter(Class> arrayClass) throws IllegalArgumentException {
+ return MethodHandleImpl.accessArrayElement(arrayClass, true);
+ }
+
+ /// method handle invocation (reflective style)
+
+ /**
+ * Produces a method handle which will invoke any method handle of the
+ * given {@code type} on a standard set of {@code Object} type arguments
+ * and a single trailing {@code Object[]} array.
+ * The resulting invoker will be a method handle with the following
+ * arguments:
+ *
+ * a single {@code MethodHandle} target
+ * zero or more {@code Object} values (counted by {@code objectArgCount})
+ * an {@code Object[]} array containing more arguments
+ *
+ *
+ * The invoker will behave like a call to {@link MethodHandle#invokeGeneric invokeGeneric} with
+ * the indicated {@code type}.
+ * That is, if the target is exactly of the given {@code type}, it will behave
+ * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
+ * is used to convert the target to the required {@code type}.
+ *
+ * The type of the returned invoker will not be the given {@code type}, but rather
+ * will have all parameter and return types replaced by {@code Object}, except for
+ * the last parameter type, which will be the array type {@code Object[]}.
+ *
+ * Before invoking its target, the invoker will spread the varargs array, apply
+ * reference casts as necessary, and unbox and widen primitive arguments.
+ * The return value of the invoker will be an {@code Object} reference,
+ * boxing a primitive value if the original type returns a primitive,
+ * and always null if the original type returns void.
+ *
+ * This method is equivalent to the following code (though it may be more efficient):
+ *
+MethodHandle invoker = MethodHandles.genericInvoker(type);
+int spreadArgCount = type.parameterCount - objectArgCount;
+invoker = invoker.asSpreader(Object[].class, spreadArgCount);
+return invoker;
+ *
+ *
+ * This method throws no reflective or security exceptions.
+ * @param type the desired target type
+ * @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
+ * @return a method handle suitable for invoking any method handle of the given type
+ */
+ static public
+ MethodHandle spreadInvoker(MethodType type, int objectArgCount) {
+ if (objectArgCount < 0 || objectArgCount > type.parameterCount())
+ throw new IllegalArgumentException("bad argument count "+objectArgCount);
+ return type.invokers().spreadInvoker(objectArgCount);
+ }
+
+ /**
+ * Produces a special invoker method handle which can be used to
+ * invoke any method handle of the given type, as if by {@code invokeExact}.
+ * The resulting invoker will have a type which is
+ * exactly equal to the desired type, except that it will accept
+ * an additional leading argument of type {@code MethodHandle}.
+ *
+ * This method is equivalent to the following code (though it may be more efficient):
+ *
+publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
+ *
+ *
+ *
+ * Discussion:
+ * Invoker method handles can be useful when working with variable method handles
+ * of unknown types.
+ * For example, to emulate an {@code invokeExact} call to a variable method
+ * handle {@code M}, extract its type {@code T},
+ * look up the invoker method {@code X} for {@code T},
+ * and call the invoker method, as {@code X.invokeGeneric(T, A...)}.
+ * (It would not work to call {@code X.invokeExact}, since the type {@code T}
+ * is unknown.)
+ * If spreading, collecting, or other argument transformations are required,
+ * they can be applied once to the invoker {@code X} and reused on many {@code M}
+ * method handle values, as long as they are compatible with the type of {@code X}.
+ *
+ * (Note: The invoker method is not available via the Core Reflection API.
+ * An attempt to call {@linkplain java.lang.reflect.Method#invoke Method.invoke}
+ * on the declared {@code invokeExact} or {@code invokeGeneric} method will raise an
+ * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)
+ *
+ * This method throws no reflective or security exceptions.
+ * @param type the desired target type
+ * @return a method handle suitable for invoking any method handle of the given type
+ */
+ static public
+ MethodHandle exactInvoker(MethodType type) {
+ return type.invokers().exactInvoker();
+ }
+
+ /**
+ * Produces a special invoker method handle which can be used to
+ * invoke any method handle of the given type, as if by {@code invokeGeneric}.
+ * The resulting invoker will have a type which is
+ * exactly equal to the desired type, except that it will accept
+ * an additional leading argument of type {@code MethodHandle}.
+ *
+ * Before invoking its target, the invoker will apply reference casts as
+ * necessary and unbox and widen primitive arguments, as if by {@link #convertArguments convertArguments}.
+ * The return value of the invoker will be an {@code Object} reference,
+ * boxing a primitive value if the original type returns a primitive,
+ * and always null if the original type returns void.
+ *
+ * This method is equivalent to the following code (though it may be more efficient):
+ *
+publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
+ *
+ *
+ * This method throws no reflective or security exceptions.
+ * @param type the desired target type
+ * @return a method handle suitable for invoking any method handle convertible to the given type
+ */
+ static public
+ MethodHandle genericInvoker(MethodType type) {
+ return type.invokers().genericInvoker();
+ }
+
+ /**
+ * Perform value checking, exactly as if for an adapted method handle.
+ * It is assumed that the given value is either null, of type T0,
+ * or (if T0 is primitive) of the wrapper type corresponding to T0.
+ * The following checks and conversions are made:
+ *
+ * If T0 and T1 are references, then a cast to T1 is applied.
+ * (The types do not need to be related in any particular way.)
+ * If T0 and T1 are primitives, then a widening or narrowing
+ * conversion is applied, if one exists.
+ * If T0 is a primitive and T1 a reference, and
+ * T0 has a wrapper type TW, a boxing conversion to TW is applied,
+ * possibly followed by a reference conversion.
+ * T1 must be TW or a supertype.
+ * If T0 is a reference and T1 a primitive, and
+ * T1 has a wrapper type TW, an unboxing conversion is applied,
+ * possibly preceded by a reference conversion.
+ * T0 must be TW or a supertype.
+ * If T1 is void, the return value is discarded
+ * If T0 is void and T1 a reference, a null value is introduced.
+ * If T0 is void and T1 a primitive, a zero value is introduced.
+ *
+ * If the value is discarded, null will be returned.
+ * @param valueType
+ * @param value
+ * @return the value, converted if necessary
+ * @throws java.lang.ClassCastException if a cast fails
+ */
+ static
+ T1 checkValue(Class t0, Class t1, Object value)
+ throws ClassCastException
+ {
+ if (t0 == t1) {
+ // no conversion needed; just reassert the same type
+ if (t0.isPrimitive())
+ return Wrapper.asPrimitiveType(t1).cast(value);
+ else
+ return Wrapper.OBJECT.convert(value, t1);
+ }
+ boolean prim0 = t0.isPrimitive(), prim1 = t1.isPrimitive();
+ if (!prim0) {
+ // check contract with caller
+ Wrapper.OBJECT.convert(value, t0);
+ if (!prim1) {
+ return Wrapper.OBJECT.convert(value, t1);
+ }
+ // convert reference to primitive by unboxing
+ Wrapper w1 = Wrapper.forPrimitiveType(t1);
+ return w1.convert(value, t1);
+ }
+ // check contract with caller:
+ Wrapper.asWrapperType(t0).cast(value);
+ Wrapper w1 = Wrapper.forPrimitiveType(t1);
+ return w1.convert(value, t1);
+ }
+
+ static
+ Object checkValue(Class> T1, Object value)
+ throws ClassCastException
+ {
+ Class> T0;
+ if (value == null)
+ T0 = Object.class;
+ else
+ T0 = value.getClass();
+ return checkValue(T0, T1, value);
+ }
+
+ /// method handle modification (creation from other method handles)
+
+ /**
+ * Produces a method handle which adapts the type of the
+ * given method handle to a new type by pairwise argument conversion.
+ * The original type and new type must have the same number of arguments.
+ * The resulting method handle is guaranteed to report a type
+ * which is equal to the desired new type.
+ *
+ * If the original type and new type are equal, returns target.
+ *
+ * The following conversions are applied as needed both to
+ * arguments and return types. Let T0 and T1 be the differing
+ * new and old parameter types (or old and new return types)
+ * for corresponding values passed by the new and old method types.
+ * Given those types T0, T1, one of the following conversions is applied
+ * if possible:
+ *
+ * If T0 and T1 are references, then a cast to T1 is applied.
+ * (The types do not need to be related in any particular way.)
+ * If T0 and T1 are primitives, then a Java method invocation
+ * conversion (JLS 5.3) is applied, if one exists.
+ * If T0 is a primitive and T1 a reference, a boxing
+ * conversion is applied if one exists, possibly followed by
+ * a reference conversion to a superclass.
+ * T1 must be a wrapper class or a supertype of one.
+ * If T0 is a reference and T1 a primitive, an unboxing
+ * conversion will be applied at runtime, possibly followed
+ * by a Java method invocation conversion (JLS 5.3)
+ * on the primitive value. (These are the widening conversions.)
+ * T0 must be a wrapper class or a supertype of one.
+ * (In the case where T0 is Object, these are the conversions
+ * allowed by java.lang.reflect.Method.invoke.)
+ * If the return type T1 is void, any returned value is discarded
+ * If the return type T0 is void and T1 a reference, a null value is introduced.
+ * If the return type T0 is void and T1 a primitive, a zero value is introduced.
+ *
+ * @param target the method handle to invoke after arguments are retyped
+ * @param newType the expected type of the new method handle
+ * @return a method handle which delegates to {@code target} after performing
+ * any necessary argument conversions, and arranges for any
+ * necessary return value conversions
+ * @throws NullPointerException if either argument is null
+ * @throws WrongMethodTypeException if the conversion cannot be made
+ * @see MethodHandle#asType
+ * @see MethodHandles#explicitCastArguments
+ */
+ public static
+ MethodHandle convertArguments(MethodHandle target, MethodType newType) {
+ MethodType oldType = target.type();
+ if (oldType.equals(newType))
+ return target;
+ MethodHandle res = null;
+ try {
+ res = MethodHandleImpl.convertArguments(target,
+ newType, oldType, null);
+ } catch (IllegalArgumentException ex) {
+ }
+ if (res == null)
+ throw new WrongMethodTypeException("cannot convert to "+newType+": "+target);
+ return res;
+ }
+
+ /**
+ * Produces a method handle which adapts the type of the
+ * given method handle to a new type by pairwise argument conversion.
+ * The original type and new type must have the same number of arguments.
+ * The resulting method handle is guaranteed to report a type
+ * which is equal to the desired new type.
+ *
+ * If the original type and new type are equal, returns target.
+ *
+ * The same conversions are allowed as for {@link #convertArguments convertArguments},
+ * and some additional conversions are also applied if those conversions fail.
+ * Given types T0, T1, one of the following conversions is applied
+ * in addition, if the conversions specified for {@code convertArguments}
+ * would be insufficient:
+ *
+ * If T0 and T1 are references, and T1 is an interface type,
+ * then the value of type T0 is passed as a T1 without a cast.
+ * (This treatment of interfaces follows the usage of the bytecode verifier.)
+ * If T0 and T1 are primitives and one is boolean,
+ * the boolean is treated as a one-bit unsigned integer.
+ * (This treatment follows the usage of the bytecode verifier.)
+ * A conversion from another primitive type behaves as if
+ * it first converts to byte, and then masks all but the low bit.
+ * If a primitive value would be converted by {@code convertArguments}
+ * using Java method invocation conversion (JLS 5.3),
+ * Java casting conversion (JLS 5.5) may be used also.
+ * This allows primitives to be narrowed as well as widened.
+ *
+ * @param target the method handle to invoke after arguments are retyped
+ * @param newType the expected type of the new method handle
+ * @return a method handle which delegates to {@code target} after performing
+ * any necessary argument conversions, and arranges for any
+ * necessary return value conversions
+ * @throws NullPointerException if either argument is null
+ * @throws WrongMethodTypeException if the conversion cannot be made
+ * @see MethodHandle#asType
+ * @see MethodHandles#convertArguments
+ */
+ public static
+ MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
+ return convertArguments(target, newType); // FIXME!
+ }
+
+ /*
+ FIXME: Reconcile javadoc with 10/22/2010 EG notes on conversion:
+
+ Both converters arrange for their method handles to convert arguments
+ and return values. The conversion rules are the same for arguments
+ and return values, and depend only on source and target types, S and
+ T. The conversions allowed by castConvertArguments are a strict
+ superset of those performed by convertArguments.
+
+ In all cases, if S and T are references, a simple checkcast is done.
+ If neither S nor T is a primitive, no attempt is made to unbox and
+ box. A failed conversion throws ClassCastException.
+
+ If T is void, the value is dropped.
+
+ For compatibility with reflection, if S is void and T is a reference,
+ a null value is produced.
+
+ For compatibility with reflection, if S is a reference and T is a
+ primitive, S is first unboxed and then undergoes primitive conversion.
+ In the case of 'convertArguments', only assignment conversion is
+ performed (no narrowing primitive conversion).
+
+ If S is a primitive, S is boxed, and then the above rules are applied.
+ If S and T are both primitives, the boxing will be undetectable; only
+ the primitive conversions will be apparent to the user. The key point
+ is that if S is a primitive type, the implementation may box it and
+ treat is as Object, without loss of information, or it may use a "fast
+ path" which does not use boxing.
+
+ Notwithstanding the rules above, for compatibility with the verifier,
+ if T is an interface, it is treated as if it were Object. [KEEP THIS?]
+
+ Also, for compatibility with the verifier, a boolean may be undergo
+ widening or narrowing conversion to any other primitive type. [KEEP THIS?]
+ */
+
+ /**
+ * Produces a method handle which adapts the calling sequence of the
+ * given method handle to a new type, by reordering the arguments.
+ * The resulting method handle is guaranteed to report a type
+ * which is equal to the desired new type.
+ *
+ * The given array controls the reordering.
+ * Call {@code #I} the number of incoming parameters (the value
+ * {@code newType.parameterCount()}, and call {@code #O} the number
+ * of outgoing parameters (the value {@code target.type().parameterCount()}).
+ * Then the length of the reordering array must be {@code #O},
+ * and each element must be a non-negative number less than {@code #I}.
+ * For every {@code N} less than {@code #O}, the {@code N}-th
+ * outgoing argument will be taken from the {@code I}-th incoming
+ * argument, where {@code I} is {@code reorder[N]}.
+ *
+ * No argument or return value conversions are applied.
+ * The type of each incoming argument, as determined by {@code newType},
+ * must be identical to the type of the corresponding outgoing argument
+ * or arguments in the target method handle.
+ * The return type of {@code newType} must be identical to the return
+ * type of the original target.
+ *
+ * The reordering array need not specify an actual permutation.
+ * An incoming argument will be duplicated if its index appears
+ * more than once in the array, and an incoming argument will be dropped
+ * if its index does not appear in the array.
+ * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
+ * incoming arguments which are not mentioned in the reordering array
+ * are may be any type, as determined only by {@code newType}.
+ *
+MethodType intfn1 = MethodType.methodType(int.class, int.class);
+MethodType intfn2 = MethodType.methodType(int.class, int.class, int.class);
+MethodHandle sub = ... {int x, int y => x-y} ...;
+assert(sub.type().equals(intfn2));
+MethodHandle sub1 = MethodHandles.permuteArguments(sub, intfn2, 0, 1);
+MethodHandle rsub = MethodHandles.permuteArguments(sub, intfn2, 1, 0);
+assert((int)rsub.invokeExact(1, 100) == 99);
+MethodHandle add = ... {int x, int y => x+y} ...;
+assert(add.type().equals(intfn2));
+MethodHandle twice = MethodHandles.permuteArguments(add, intfn1, 0, 0);
+assert(twice.type().equals(intfn1));
+assert((int)twice.invokeExact(21) == 42);
+ *
+ * @param target the method handle to invoke after arguments are reordered
+ * @param newType the expected type of the new method handle
+ * @param reorder a string which controls the reordering
+ * @return a method handle which delegates to {@code target} after it
+ * drops unused arguments and moves and/or duplicates the other arguments
+ * @throws NullPointerException if any argument is null
+ */
+ public static
+ MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
+ MethodType oldType = target.type();
+ checkReorder(reorder, newType, oldType);
+ return MethodHandleImpl.convertArguments(target,
+ newType, oldType,
+ reorder);
+ }
+
+ private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
+ if (reorder.length == oldType.parameterCount()) {
+ int limit = newType.parameterCount();
+ boolean bad = false;
+ for (int i : reorder) {
+ if (i < 0 || i >= limit) {
+ bad = true; break;
+ }
+ }
+ if (!bad) return;
+ }
+ throw newIllegalArgumentException("bad reorder array");
+ }
+
+ /**
+ * Equivalent to the following code:
+ *
+ * int spreadPos = newType.parameterCount() - 1;
+ * Class<?> spreadType = newType.parameterType(spreadPos);
+ * int spreadCount = target.type().parameterCount() - spreadPos;
+ * MethodHandle adapter = target.asSpreader(spreadType, spreadCount);
+ * adapter = adapter.asType(newType);
+ * return adapter;
+ *
+ * @param target the method handle to invoke after argument spreading
+ * @param newType the expected type of the new method handle
+ * @return a method handle which spreads its final argument,
+ * before calling the original method handle
+ */
+ /*non-public*/ static
+ MethodHandle spreadArguments(MethodHandle target, MethodType newType) {
+ MethodType oldType = target.type();
+ int inargs = newType.parameterCount();
+ int outargs = oldType.parameterCount();
+ int spreadPos = inargs - 1;
+ int numSpread = (outargs - spreadPos);
+ MethodHandle res = null;
+ if (spreadPos >= 0 && numSpread >= 0) {
+ res = MethodHandleImpl.spreadArguments(target, newType, spreadPos);
+ }
+ if (res == null) {
+ throw newIllegalArgumentException("cannot spread "+newType+" to " +oldType);
+ }
+ return res;
+ }
+
+ /**
+ * Equivalent to the following code:
+ *
+ * int collectPos = target.type().parameterCount() - 1;
+ * Class<?> collectType = target.type().parameterType(collectPos);
+ * if (!collectType.isArray()) collectType = Object[].class;
+ * int collectCount = newType.parameterCount() - collectPos;
+ * MethodHandle adapter = target.asCollector(collectType, collectCount);
+ * adapter = adapter.asType(newType);
+ * return adapter;
+ *
+ * @param target the method handle to invoke after argument collection
+ * @param newType the expected type of the new method handle
+ * @return a method handle which collects some trailing argument
+ * into an array, before calling the original method handle
+ */
+ /*non-public*/ static
+ MethodHandle collectArguments(MethodHandle target, MethodType newType) {
+ MethodType oldType = target.type();
+ int inargs = newType.parameterCount();
+ int outargs = oldType.parameterCount();
+ int collectPos = outargs - 1;
+ int numCollect = (inargs - collectPos);
+ if (collectPos < 0 || numCollect < 0)
+ throw newIllegalArgumentException("wrong number of arguments");
+ MethodHandle res = MethodHandleImpl.collectArguments(target, newType, collectPos, null);
+ if (res == null) {
+ throw newIllegalArgumentException("cannot collect from "+newType+" to " +oldType);
+ }
+ return res;
+ }
+
+ /**
+ * Produces a method handle of the requested return type which returns the given
+ * constant value every time it is invoked.
+ *
+ * Before the method handle is returned, the passed-in value is converted to the requested type.
+ * If the requested type is primitive, widening primitive conversions are attempted,
+ * else reference conversions are attempted.
+ *
The returned method handle is equivalent to {@code identity(type).bindTo(value)},
+ * unless the type is {@code void}, in which case it is {@code identity(type)}.
+ * @param type the return type of the desired method handle
+ * @param value the value to return
+ * @return a method handle of the given return type and no arguments, which always returns the given value
+ * @throws NullPointerException if the {@code type} argument is null
+ * @throws ClassCastException if the value cannot be converted to the required return type
+ * @throws IllegalArgumentException if the given type is {@code void.class}
+ */
+ public static
+ MethodHandle constant(Class> type, Object value) {
+ if (type.isPrimitive()) {
+ if (type == void.class)
+ throw newIllegalArgumentException("void type");
+ Wrapper w = Wrapper.forPrimitiveType(type);
+ return identity(type).bindTo(w.convert(value, type));
+ } else {
+ return identity(type).bindTo(type.cast(value));
+ }
+ }
+
+ /**
+ * Produces a method handle which returns its sole argument when invoked.
+ *
The identity function for {@code void} takes no arguments and returns no values.
+ * @param type the type of the sole parameter and return value of the desired method handle
+ * @return a unary method handle which accepts and returns the given type
+ * @throws NullPointerException if the argument is null
+ * @throws IllegalArgumentException if the given type is {@code void.class}
+ */
+ public static
+ MethodHandle identity(Class> type) {
+ if (type == void.class)
+ throw newIllegalArgumentException("void type");
+ else if (type == Object.class)
+ return ValueConversions.identity();
+ else if (type.isPrimitive())
+ return ValueConversions.identity(Wrapper.forPrimitiveType(type));
+ else
+ return AdapterMethodHandle.makeRetypeRaw(
+ MethodType.methodType(type, type), ValueConversions.identity());
+ }
+
+ /**
+ * Produces a method handle which calls the original method handle {@code target},
+ * after inserting the given argument(s) at the given position.
+ * The formal parameters to {@code target} which will be supplied by those
+ * arguments are called bound parameters , because the new method
+ * will contain bindings for those parameters take from {@code values}.
+ * The type of the new method handle will drop the types for the bound
+ * parameters from the original target type, since the new method handle
+ * will no longer require those arguments to be supplied by its callers.
+ *
+ * Each given argument object must match the corresponding bound parameter type.
+ * If a bound parameter type is a primitive, the argument object
+ * must be a wrapper, and will be unboxed to produce the primitive value.
+ *
+ * The pos may range between zero and N (inclusively),
+ * where N is the number of argument types in resulting method handle
+ * (after bound parameter types are dropped).
+ * @param target the method handle to invoke after the argument is inserted
+ * @param pos where to insert the argument (zero for the first)
+ * @param values the series of arguments to insert
+ * @return a method handle which inserts an additional argument,
+ * before calling the original method handle
+ * @throws NullPointerException if the {@code target} argument or the {@code values} array is null
+ * @see MethodHandle#bindTo
+ */
+ public static
+ MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
+ int insCount = values.length;
+ MethodType oldType = target.type();
+ int outargs = oldType.parameterCount();
+ int inargs = outargs - insCount;
+ if (inargs < 0)
+ throw newIllegalArgumentException("too many values to insert");
+ if (pos < 0 || pos > inargs)
+ throw newIllegalArgumentException("no argument type to append");
+ MethodHandle result = target;
+ for (int i = 0; i < insCount; i++) {
+ Object value = values[i];
+ Class> valueType = oldType.parameterType(pos+i);
+ value = checkValue(valueType, value);
+ if (pos == 0 && !valueType.isPrimitive()) {
+ // At least for now, make bound method handles a special case.
+ MethodHandle bmh = MethodHandleImpl.bindReceiver(result, value);
+ if (bmh != null) {
+ result = bmh;
+ continue;
+ }
+ // else fall through to general adapter machinery
+ }
+ result = MethodHandleImpl.bindArgument(result, pos, value);
+ }
+ return result;
+ }
+
+ /**
+ * Produces a method handle which calls the original method handle,
+ * after dropping the given argument(s) at the given position.
+ * The type of the new method handle will insert the given argument
+ * type(s), at that position, into the original handle's type.
+ *
+ * The pos may range between zero and N ,
+ * where N is the number of argument types in target ,
+ * meaning to drop the first or last argument (respectively),
+ * or an argument somewhere in between.
+ *
+ * Example:
+ *
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
+MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
+assertEquals(bigType, d0.type());
+assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
+ *
+ *
+ * This method is also equivalent to the following code:
+ *
+ * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}(target, pos, valueTypes.toArray(new Class[0]))
+ *
+ * @param target the method handle to invoke after the arguments are dropped
+ * @param valueTypes the type(s) of the argument(s) to drop
+ * @param pos position of first argument to drop (zero for the leftmost)
+ * @return a method handle which drops arguments of the given types,
+ * before calling the original method handle
+ * @throws NullPointerException if the {@code target} argument is null,
+ * or if the {@code valueTypes} list or any of its elements is null
+ * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
+ */
+ public static
+ MethodHandle dropArguments(MethodHandle target, int pos, List> valueTypes) {
+ if (valueTypes.size() == 0) return target;
+ MethodType oldType = target.type();
+ int outargs = oldType.parameterCount();
+ int inargs = outargs + valueTypes.size();
+ if (pos < 0 || pos >= inargs)
+ throw newIllegalArgumentException("no argument type to remove");
+ ArrayList> ptypes =
+ new ArrayList>(oldType.parameterList());
+ ptypes.addAll(pos, valueTypes);
+ MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
+ return MethodHandleImpl.dropArguments(target, newType, pos);
+ }
+
+ /**
+ * Produces a method handle which calls the original method handle,
+ * after dropping the given argument(s) at the given position.
+ * The type of the new method handle will insert the given argument
+ * type(s), at that position, into the original handle's type.
+ *
+ * The pos may range between zero and N ,
+ * where N is the number of argument types in target ,
+ * meaning to drop the first or last argument (respectively),
+ * or an argument somewhere in between.
+ *
+ * Example:
+ *
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodHandle d0 = dropArguments(cat, 0, String.class);
+assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
+MethodHandle d1 = dropArguments(cat, 1, String.class);
+assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
+MethodHandle d2 = dropArguments(cat, 2, String.class);
+assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
+MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
+assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
+ *
+ *
+ * This method is also equivalent to the following code:
+ *
+ * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
+ *
+ * @param target the method handle to invoke after the arguments are dropped
+ * @param valueTypes the type(s) of the argument(s) to drop
+ * @param pos position of first argument to drop (zero for the leftmost)
+ * @return a method handle which drops arguments of the given types,
+ * before calling the original method handle
+ * @throws NullPointerException if the {@code target} argument is null,
+ * or if the {@code valueTypes} array or any of its elements is null
+ * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
+ */
+ public static
+ MethodHandle dropArguments(MethodHandle target, int pos, Class>... valueTypes) {
+ return dropArguments(target, pos, Arrays.asList(valueTypes));
+ }
+
+ /**
+ * Adapts a target method handle {@code target} by pre-processing
+ * one or more of its arguments, each with its own unary filter function,
+ * and then calling the target with each pre-processed argument
+ * replaced by the result of its corresponding filter function.
+ *
+ * The pre-processing is performed by one or more method handles,
+ * specified in the elements of the {@code filters} array.
+ * Null arguments in the array are ignored, and the corresponding arguments left unchanged.
+ * (If there are no non-null elements in the array, the original target is returned.)
+ * Each filter is applied to the corresponding argument of the adapter.
+ *
+ * If a filter {@code F} applies to the {@code N}th argument of
+ * the method handle, then {@code F} must be a method handle which
+ * takes exactly one argument. The type of {@code F}'s sole argument
+ * replaces the corresponding argument type of the target
+ * in the resulting adapted method handle.
+ * The return type of {@code F} must be identical to the corresponding
+ * parameter type of the target.
+ *
+ * It is an error if there are elements of {@code filters}
+ * which do not correspond to argument positions in the target.
+ * Example:
+ *
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+MethodHandle upcase = lookup().findVirtual(String.class,
+ "toUpperCase", methodType(String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodHandle f0 = filterArguments(cat, 0, upcase);
+assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
+MethodHandle f1 = filterArguments(cat, 1, upcase);
+assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
+MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
+assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
+ *
+ *
+ * @param target the method handle to invoke after arguments are filtered
+ * @param pos the position of the first argument to filter
+ * @param filters method handles to call initially on filtered arguments
+ * @return method handle which incorporates the specified argument filtering logic
+ * @throws NullPointerException if the {@code target} argument is null
+ * or if the {@code filters} array is null
+ * @throws IllegalArgumentException if a non-null element of {@code filters}
+ * does not match a corresponding argument type of {@code target} as described above,
+ * or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}
+ */
+ public static
+ MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
+ MethodType targetType = target.type();
+ MethodHandle adapter = target;
+ MethodType adapterType = targetType;
+ int maxPos = targetType.parameterCount();
+ if (pos + filters.length > maxPos)
+ throw newIllegalArgumentException("too many filters");
+ int curPos = pos-1; // pre-incremented
+ for (MethodHandle filter : filters) {
+ curPos += 1;
+ if (filter == null) continue; // ignore null elements of filters
+ MethodType filterType = filter.type();
+ if (filterType.parameterCount() != 1
+ || filterType.returnType() != targetType.parameterType(curPos))
+ throw newIllegalArgumentException("target and filter types do not match");
+ adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0));
+ adapter = MethodHandleImpl.filterArgument(adapter, curPos, filter);
+ }
+ MethodType midType = adapter.type();
+ if (midType != adapterType)
+ adapter = MethodHandleImpl.convertArguments(adapter, adapterType, midType, null);
+ return adapter;
+ }
+
+ /**
+ * Adapts a target method handle {@code target} by post-processing
+ * its return value with a unary filter function.
+ *
+ * If a filter {@code F} applies to the return value of
+ * the target method handle, then {@code F} must be a method handle which
+ * takes exactly one argument. The return type of {@code F}
+ * replaces the return type of the target
+ * in the resulting adapted method handle.
+ * The argument type of {@code F} must be identical to the
+ * return type of the target.
+ * Example:
+ *
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+MethodHandle length = lookup().findVirtual(String.class,
+ "length", methodType(int.class));
+System.out.println((String) cat.invokeExact("x", "y")); // xy
+MethodHandle f0 = filterReturnValue(cat, length);
+System.out.println((int) f0.invokeExact("x", "y")); // 2
+ *
+ * @param target the method handle to invoke before filtering the return value
+ * @param filter method handle to call on the return value
+ * @return method handle which incorporates the specified return value filtering logic
+ * @throws NullPointerException if either argument is null
+ * @throws IllegalArgumentException if {@code filter}
+ * does not match the return type of {@code target} as described above
+ */
+ public static
+ MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
+ MethodType targetType = target.type();
+ MethodType filterType = filter.type();
+ if (filterType.parameterCount() != 1
+ || filterType.parameterType(0) != targetType.returnType())
+ throw newIllegalArgumentException("target and filter types do not match");
+ // result = fold( lambda(retval, arg...) { filter(retval) },
+ // lambda( arg...) { target(arg...) } )
+ // FIXME: Too many nodes here.
+ MethodHandle returner = dropArguments(filter, 1, targetType.parameterList());
+ return foldArguments(returner, target);
+ }
+
+ /**
+ * Adapts a target method handle {@code target} by pre-processing
+ * some of its arguments, and then calling the target with
+ * the result of the pre-processing, plus all original arguments.
+ *
+ * The pre-processing is performed by a second method handle, the {@code combiner}.
+ * The first {@code N} arguments passed to the adapter,
+ * are copied to the combiner, which then produces a result.
+ * (Here, {@code N} is defined as the parameter count of the adapter.)
+ * After this, control passes to the {@code target}, with both the result
+ * of the combiner, and all the original incoming arguments.
+ *
+ * The first argument type of the target must be identical with the
+ * return type of the combiner.
+ * The resulting adapter is the same type as the target, except that the
+ * initial argument type of the target is dropped.
+ *
+ * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
+ * that either the {@code combiner} or {@code target} does not wish to receive.
+ * If some of the incoming arguments are destined only for the combiner,
+ * consider using {@link MethodHandle#asCollector asCollector} instead, since those
+ * arguments will not need to be live on the stack on entry to the
+ * target.)
+ *
+ * The first argument of the target must be identical with the
+ * return value of the combiner.
+ *
Here is pseudocode for the resulting adapter:
+ *
+ * // there are N arguments in the A sequence
+ * T target(V, A[N]..., B...);
+ * V combiner(A...);
+ * T adapter(A... a, B... b) {
+ * V v = combiner(a...);
+ * return target(v, a..., b...);
+ * }
+ *
+ * @param target the method handle to invoke after arguments are combined
+ * @param combiner method handle to call initially on the incoming arguments
+ * @return method handle which incorporates the specified argument folding logic
+ * @throws NullPointerException if either argument is null
+ * @throws IllegalArgumentException if the first argument type of
+ * {@code target} is not the same as {@code combiner}'s return type,
+ * or if the following argument types of {@code target}
+ * are not identical with the argument types of {@code combiner}
+ */
+ public static
+ MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
+ MethodType targetType = target.type();
+ MethodType combinerType = combiner.type();
+ int foldArgs = combinerType.parameterCount();
+ boolean ok = (targetType.parameterCount() >= 1 + foldArgs);
+ if (ok && !combinerType.parameterList().equals(targetType.parameterList().subList(1, foldArgs+1)))
+ ok = false;
+ if (ok && !combinerType.returnType().equals(targetType.parameterType(0)))
+ ok = false;
+ if (!ok)
+ throw misMatchedTypes("target and combiner types", targetType, combinerType);
+ MethodType newType = targetType.dropParameterTypes(0, 1);
+ return MethodHandleImpl.foldArguments(target, newType, combiner);
+ }
+
+ /**
+ * Makes a method handle which adapts a target method handle,
+ * by guarding it with a test, a boolean-valued method handle.
+ * If the guard fails, a fallback handle is called instead.
+ * All three method handles must have the same corresponding
+ * argument and return types, except that the return type
+ * of the test must be boolean, and the test is allowed
+ * to have fewer arguments than the other two method handles.
+ * Here is pseudocode for the resulting adapter:
+ *
+ * boolean test(A...);
+ * T target(A...,B...);
+ * T fallback(A...,B...);
+ * T adapter(A... a,B... b) {
+ * if (test(a...))
+ * return target(a..., b...);
+ * else
+ * return fallback(a..., b...);
+ * }
+ *
+ * Note that the test arguments ({@code a...} in the pseudocode) cannot
+ * be modified by execution of the test, and so are passed unchanged
+ * from the caller to the target or fallback as appropriate.
+ * @param test method handle used for test, must return boolean
+ * @param target method handle to call if test passes
+ * @param fallback method handle to call if test fails
+ * @return method handle which incorporates the specified if/then/else logic
+ * @throws NullPointerException if any argument is null
+ * @throws IllegalArgumentException if {@code test} does not return boolean,
+ * or if all three method types do not match (with the return
+ * type of {@code test} changed to match that of {@code target}).
+ */
+ public static
+ MethodHandle guardWithTest(MethodHandle test,
+ MethodHandle target,
+ MethodHandle fallback) {
+ MethodType gtype = test.type();
+ MethodType ttype = target.type();
+ MethodType ftype = fallback.type();
+ if (!ttype.equals(ftype))
+ throw misMatchedTypes("target and fallback types", ttype, ftype);
+ if (gtype.returnType() != boolean.class)
+ throw newIllegalArgumentException("guard type is not a predicate "+gtype);
+ List> targs = ttype.parameterList();
+ List> gargs = gtype.parameterList();
+ if (!targs.equals(gargs)) {
+ int gpc = gargs.size(), tpc = targs.size();
+ if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
+ throw misMatchedTypes("target and test types", ttype, gtype);
+ test = dropArguments(test, gpc, targs.subList(gpc, tpc));
+ gtype = test.type();
+ }
+ return MethodHandleImpl.makeGuardWithTest(test, target, fallback);
+ }
+
+ static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
+ return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
+ }
+
+ /**
+ * Makes a method handle which adapts a target method handle,
+ * by running it inside an exception handler.
+ * If the target returns normally, the adapter returns that value.
+ * If an exception matching the specified type is thrown, the fallback
+ * handle is called instead on the exception, plus the original arguments.
+ *
+ * The target and handler must have the same corresponding
+ * argument and return types, except that handler may omit trailing arguments
+ * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
+ * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
+ *
Here is pseudocode for the resulting adapter:
+ *
+ * T target(A..., B...);
+ * T handler(ExType, A...);
+ * T adapter(A... a, B... b) {
+ * try {
+ * return target(a..., b...);
+ * } catch (ExType ex) {
+ * return handler(ex, a...);
+ * }
+ * }
+ *
+ * Note that the saved arguments ({@code a...} in the pseudocode) cannot
+ * be modified by execution of the target, and so are passed unchanged
+ * from the caller to the handler, if the handler is invoked.
+ *
+ * The target and handler must return the same type, even if the handler
+ * always throws. (This might happen, for instance, because the handler
+ * is simulating a {@code finally} clause).
+ * To create such a throwing handler, compose the handler creation logic
+ * with {@link #throwException throwException},
+ * in order to create a method handle of the correct return type.
+ * @param target method handle to call
+ * @param exType the type of exception which the handler will catch
+ * @param handler method handle to call if a matching exception is thrown
+ * @return method handle which incorporates the specified try/catch logic
+ * @throws NullPointerException if any argument is null
+ * @throws IllegalArgumentException if {@code handler} does not accept
+ * the given exception type, or if the method handle types do
+ * not match in their return types and their
+ * corresponding parameters
+ */
+ public static
+ MethodHandle catchException(MethodHandle target,
+ Class extends Throwable> exType,
+ MethodHandle handler) {
+ MethodType ttype = target.type();
+ MethodType htype = handler.type();
+ if (htype.parameterCount() < 1 ||
+ !htype.parameterType(0).isAssignableFrom(exType))
+ throw newIllegalArgumentException("handler does not accept exception type "+exType);
+ if (htype.returnType() != ttype.returnType())
+ throw misMatchedTypes("target and handler return types", ttype, htype);
+ List> targs = ttype.parameterList();
+ List> hargs = htype.parameterList();
+ hargs = hargs.subList(1, hargs.size()); // omit leading parameter from handler
+ if (!targs.equals(hargs)) {
+ int hpc = hargs.size(), tpc = targs.size();
+ if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
+ throw misMatchedTypes("target and handler types", ttype, htype);
+ handler = dropArguments(handler, hpc, hargs.subList(hpc, tpc));
+ htype = handler.type();
+ }
+ return MethodHandleImpl.makeGuardWithCatch(target, exType, handler);
+ }
+
+ /**
+ * Produces a method handle which will throw exceptions of the given {@code exType}.
+ * The method handle will accept a single argument of {@code exType},
+ * and immediately throw it as an exception.
+ * The method type will nominally specify a return of {@code returnType}.
+ * The return type may be anything convenient: It doesn't matter to the
+ * method handle's behavior, since it will never return normally.
+ * @return method handle which can throw the given exceptions
+ * @throws NullPointerException if either argument is null
+ */
+ public static
+ MethodHandle throwException(Class> returnType, Class extends Throwable> exType) {
+ return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
+ }
+
+ /**
+ * Produces an instance of the given single-method interface which redirects
+ * its calls to the given method handle.
+ *
+ * A single-method interface is an interface which declares a unique method.
+ * When determining the unique method of a single-method interface,
+ * the public {@code Object} methods ({@code toString}, {@code equals}, {@code hashCode})
+ * are disregarded. For example, {@link java.util.Comparator} is a single-method interface,
+ * even though it re-declares the {@code Object.equals} method.
+ *
+ * The type must be public. No additional access checks are performed.
+ *
+ * The resulting instance of the required type will respond to
+ * invocation of the type's single abstract method by calling
+ * the given {@code target} on the incoming arguments,
+ * and returning or throwing whatever the {@code target}
+ * returns or throws. The invocation will be as if by
+ * {@code target.invokeGeneric}.
+ * The target's type will be checked before the
+ * instance is created, as if by a call to {@code asType},
+ * which may result in a {@code WrongMethodTypeException}.
+ *
+ * The wrapper instance will implement the requested interface
+ * and its super-types, but no other single-method interfaces.
+ * This means that the instance will not unexpectedly
+ * pass an {@code instanceof} test for any unrequested type.
+ *
+ * Implementation Note:
+ * Therefore, each instance must implement a unique single-method interface.
+ * Implementations may not bundle together
+ * multiple single-method interfaces onto single implementation classes
+ * in the style of {@link java.awt.AWTEventMulticaster}.
+ *
+ * The method handle may throw an undeclared exception ,
+ * which means any checked exception (or other checked throwable)
+ * not declared by the requested type's single abstract method.
+ * If this happens, the throwable will be wrapped in an instance of
+ * {@link java.lang.reflect.UndeclaredThrowableException UndeclaredThrowableException}
+ * and thrown in that wrapped form.
+ *
+ * Like {@link java.lang.Integer#valueOf Integer.valueOf},
+ * {@code asInstance} is a factory method whose results are defined
+ * by their behavior.
+ * It is not guaranteed to return a new instance for every call.
+ *
+ * Because of the possibility of {@linkplain java.lang.reflect.Method#isBridge bridge methods}
+ * and other corner cases, the interface may also have several abstract methods
+ * with the same name but having distinct descriptors (types of returns and parameters).
+ * In this case, all the methods are bound in common to the one given {@code target}.
+ * The type check and effective {@code asType} conversion is applied to each
+ * method type descriptor, and all abstract methods are bound to the {@code target} in common.
+ * Beyond this type check, no further checks are made to determine that the
+ * abstract methods are related in any way.
+ *
+ * Future versions of this API may accept additional types,
+ * such as abstract classes with single abstract methods.
+ * Future versions of this API may also equip wrapper instances
+ * with one or more additional public "marker" interfaces.
+ *
+ * @param target the method handle to invoke from the wrapper
+ * @param smType the desired type of the wrapper, a single-method interface
+ * @return a correctly-typed wrapper for the given {@code target}
+ * @throws NullPointerException if either argument is null
+ * @throws IllegalArgumentException if the {@code smType} is not a
+ * valid argument to this method
+ * @throws WrongMethodTypeException if the {@code target} cannot
+ * be converted to the type required by the requested interface
+ */
+ // Other notes to implementors:
+ //
+ // No stable mapping is promised between the single-method interface and
+ // the implementation class C. Over time, several implementation
+ // classes might be used for the same type.
+ //
+ // If the implementation is able
+ // to prove that a wrapper of the required type
+ // has already been created for a given
+ // method handle, or for another method handle with the
+ // same behavior, the implementation may return that wrapper in place of
+ // a new wrapper.
+ //
+ // This method is designed to apply to common use cases
+ // where a single method handle must interoperate with
+ // an interface that implements a function-like
+ // API. Additional variations, such as single-abstract-method classes with
+ // private constructors, or interfaces with multiple but related
+ // entry points, must be covered by hand-written or automatically
+ // generated adapter classes.
+ //
+ public static
+ T asInstance(final MethodHandle target, final Class smType) {
+ // POC implementation only; violates the above contract several ways
+ final Method sm = getSingleMethod(smType);
+ if (sm == null)
+ throw new IllegalArgumentException("not a single-method interface: "+smType.getName());
+ MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
+ MethodHandle checkTarget = target.asType(smMT); // make throw WMT
+ checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
+ final MethodHandle vaTarget = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
+ return smType.cast(Proxy.newProxyInstance(
+ smType.getClassLoader(),
+ new Class[]{ smType, WrapperInstance.class },
+ new InvocationHandler() {
+ private Object getArg(String name) {
+ if ((Object)name == "getWrapperInstanceTarget") return target;
+ if ((Object)name == "getWrapperInstanceType") return smType;
+ throw new AssertionError();
+ }
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.getDeclaringClass() == WrapperInstance.class)
+ return getArg(method.getName());
+ if (method.equals(sm))
+ return vaTarget.invokeExact(args);
+ if (isObjectMethod(method))
+ return callObjectMethod(this, method, args);
+ throw new InternalError();
+ }
+ }));
+ }
+
+ /**
+ * Determines if the given object was produced by a call to {@link #asInstance asInstance}.
+ * @param x any reference
+ * @return true if the reference is not null and points to an object produced by {@code asInstance}
+ */
+ public static
+ boolean isWrapperInstance(Object x) {
+ return x instanceof WrapperInstance;
+ }
+
+ private static WrapperInstance asWrapperInstance(Object x) {
+ try {
+ if (x != null)
+ return (WrapperInstance) x;
+ } catch (ClassCastException ex) {
+ }
+ throw new IllegalArgumentException("not a wrapper instance");
+ }
+
+ /**
+ * Produces or recovers a target method handle which is behaviorally
+ * equivalent to the unique method of this wrapper instance.
+ * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
+ * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
+ * @param x any reference
+ * @return a method handle implementing the unique method
+ * @throws IllegalArgumentException if the reference x is not to a wrapper instance
+ */
+ public static
+ MethodHandle wrapperInstanceTarget(Object x) {
+ return asWrapperInstance(x).getWrapperInstanceTarget();
+ }
+
+ /**
+ * Recovers the unique single-method interface type for which this wrapper instance was created.
+ * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
+ * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
+ * @param x any reference
+ * @return the single-method interface type for which the wrapper was created
+ * @throws IllegalArgumentException if the reference x is not to a wrapper instance
+ */
+ public static
+ Class> wrapperInstanceType(Object x) {
+ return asWrapperInstance(x).getWrapperInstanceType();
+ }
+
+ private static
+ boolean isObjectMethod(Method m) {
+ switch (m.getName()) {
+ case "toString":
+ return (m.getReturnType() == String.class
+ && m.getParameterTypes().length == 0);
+ case "hashCode":
+ return (m.getReturnType() == int.class
+ && m.getParameterTypes().length == 0);
+ case "equals":
+ return (m.getReturnType() == boolean.class
+ && m.getParameterTypes().length == 1
+ && m.getParameterTypes()[0] == Object.class);
+ }
+ return false;
+ }
+
+ private static
+ Object callObjectMethod(Object self, Method m, Object[] args) {
+ assert(isObjectMethod(m)) : m;
+ switch (m.getName()) {
+ case "toString":
+ return self.getClass().getName() + "@" + Integer.toHexString(self.hashCode());
+ case "hashCode":
+ return System.identityHashCode(self);
+ case "equals":
+ return (self == args[0]);
+ }
+ return null;
+ }
+
+ private static
+ Method getSingleMethod(Class> smType) {
+ Method sm = null;
+ for (Method m : smType.getMethods()) {
+ int mod = m.getModifiers();
+ if (Modifier.isAbstract(mod)) {
+ if (sm != null && !isObjectMethod(sm))
+ return null; // too many abstract methods
+ sm = m;
+ }
+ }
+ if (!smType.isInterface() && getSingleConstructor(smType) == null)
+ return null; // wrong kind of constructor
+ return sm;
+ }
+
+ private static
+ Constructor getSingleConstructor(Class> smType) {
+ for (Constructor c : smType.getDeclaredConstructors()) {
+ if (c.getParameterTypes().length == 0) {
+ int mod = c.getModifiers();
+ if (Modifier.isPublic(mod) || Modifier.isProtected(mod))
+ return c;
+ }
+ }
+ return null;
+ }
+
+ /*non-public*/
+ static MethodHandle asVarargsCollector(MethodHandle target, Class> arrayType) {
+ return MethodHandleImpl.asVarargsCollector(target, arrayType);
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MethodType.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,841 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import sun.invoke.util.BytecodeDescriptor;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A method type represents the arguments and return type accepted and
+ * returned by a method handle, or the arguments and return type passed
+ * and expected by a method handle caller. Method types must be properly
+ * matched between a method handle and all its callers,
+ * and the JVM's operations enforce this matching at, specifically
+ * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
+ * and {@link MethodHandle#invokeGeneric MethodHandle.invokeGeneric}, and during execution
+ * of {@code invokedynamic} instructions.
+ *
+ * The structure is a return type accompanied by any number of parameter types.
+ * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
+ * (For ease of exposition, we treat {@code void} as if it were a type.
+ * In fact, it denotes the absence of a return type.)
+ *
+ * All instances of {@code MethodType} are immutable.
+ * Two instances are completely interchangeable if they compare equal.
+ * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
+ *
+ * This type can be created only by factory methods.
+ * All factory methods may cache values, though caching is not guaranteed.
+ * Some factory methods are static, while others are virtual methods which
+ * modify precursor method types, e.g., by changing a selected parameter.
+ *
+ * Factory methods which operate on groups of parameter types
+ * are systematically presented in two versions, so that both Java arrays and
+ * Java lists can be used to work with groups of parameter types.
+ * The query methods {@code parameterArray} and {@code parameterList}
+ * also provide a choice between arrays and lists.
+ *
+ * {@code MethodType} objects are sometimes derived from bytecode instructions
+ * such as {@code invokedynamic}, specifically from the type descriptor strings associated
+ * with the instructions in a class file's constant pool.
+ *
+ * Like classes and strings, method types can also be represented directly
+ * in a class file's constant pool as constants.
+ * A method type may be loaded by an {@code ldc} instruction which refers
+ * to a suitable {@code CONSTANT_MethodType} constant pool entry.
+ * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
+ * For more details, see the package summary .
+ *
+ * When the JVM materializes a {@code MethodType} from a descriptor string,
+ * all classes named in the descriptor must be accessible, and will be loaded.
+ * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
+ * This loading may occur at any time before the {@code MethodType} object is first derived.
+ * @author John Rose, JSR 292 EG
+ */
+public final
+class MethodType implements java.io.Serializable {
+ private static final long serialVersionUID = 292L; // {rtype, {ptype...}}
+
+ // The rtype and ptypes fields define the structural identity of the method type:
+ private final Class> rtype;
+ private final Class>[] ptypes;
+
+ // The remaining fields are caches of various sorts:
+ private MethodTypeForm form; // erased form, plus cached data about primitives
+ private MethodType wrapAlt; // alternative wrapped/unwrapped version
+ private Invokers invokers; // cache of handy higher-order adapters
+
+ /**
+ * Check the given parameters for validity and store them into the final fields.
+ */
+ private MethodType(Class> rtype, Class>[] ptypes) {
+ checkRtype(rtype);
+ checkPtypes(ptypes);
+ this.rtype = rtype;
+ this.ptypes = ptypes;
+ }
+
+ /*trusted*/ MethodTypeForm form() { return form; }
+ /*trusted*/ Class> rtype() { return rtype; }
+ /*trusted*/ Class>[] ptypes() { return ptypes; }
+
+ private static void checkRtype(Class> rtype) {
+ rtype.equals(rtype); // null check
+ }
+ private static int checkPtype(Class> ptype) {
+ ptype.getClass(); //NPE
+ if (ptype == void.class)
+ throw newIllegalArgumentException("parameter type cannot be void");
+ if (ptype == double.class || ptype == long.class) return 1;
+ return 0;
+ }
+ /** Return number of extra slots (count of long/double args). */
+ private static int checkPtypes(Class>[] ptypes) {
+ int slots = 0;
+ for (Class> ptype : ptypes) {
+ slots += checkPtype(ptype);
+ }
+ checkSlotCount(ptypes.length + slots);
+ return slots;
+ }
+ private static void checkSlotCount(int count) {
+ if ((count & 0xFF) != count)
+ throw newIllegalArgumentException("bad parameter count "+count);
+ }
+ private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
+ if (num instanceof Integer) num = "bad index: "+num;
+ return new IndexOutOfBoundsException(num.toString());
+ }
+
+ static final HashMap internTable
+ = new HashMap();
+
+ static final Class>[] NO_PTYPES = {};
+
+ /**
+ * Finds or creates an instance of the given method type.
+ * @param rtype the return type
+ * @param ptypes the parameter types
+ * @return a method type with the given components
+ * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+ * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
+ */
+ public static
+ MethodType methodType(Class> rtype, Class>[] ptypes) {
+ return makeImpl(rtype, ptypes, false);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @return a method type with the given components
+ * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+ * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
+ */
+ public static
+ MethodType methodType(Class> rtype, List> ptypes) {
+ boolean notrust = false; // random List impl. could return evil ptypes array
+ return makeImpl(rtype, ptypes.toArray(NO_PTYPES), notrust);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * The leading parameter type is prepended to the remaining array.
+ * @return a method type with the given components
+ * @throws NullPointerException if {@code rtype} or {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is null
+ * @throws IllegalArgumentException if {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is {@code void.class}
+ */
+ public static
+ MethodType methodType(Class> rtype, Class> ptype0, Class>... ptypes) {
+ Class>[] ptypes1 = new Class>[1+ptypes.length];
+ ptypes1[0] = ptype0;
+ System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
+ return makeImpl(rtype, ptypes1, true);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * The resulting method has no parameter types.
+ * @return a method type with the given return value
+ * @throws NullPointerException if {@code rtype} is null
+ */
+ public static
+ MethodType methodType(Class> rtype) {
+ return makeImpl(rtype, NO_PTYPES, true);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * The resulting method has the single given parameter type.
+ * @return a method type with the given return value and parameter type
+ * @throws NullPointerException if {@code rtype} or {@code ptype0} is null
+ * @throws IllegalArgumentException if {@code ptype0} is {@code void.class}
+ */
+ public static
+ MethodType methodType(Class> rtype, Class> ptype0) {
+ return makeImpl(rtype, new Class>[]{ ptype0 }, true);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * The resulting method has the same parameter types as {@code ptypes},
+ * and the specified return type.
+ * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
+ */
+ public static
+ MethodType methodType(Class> rtype, MethodType ptypes) {
+ return makeImpl(rtype, ptypes.ptypes, true);
+ }
+
+ /**
+ * Sole factory method to find or create an interned method type.
+ * @param rtype desired return type
+ * @param ptypes desired parameter types
+ * @param trusted whether the ptypes can be used without cloning
+ * @return the unique method type of the desired structure
+ */
+ /*trusted*/ static
+ MethodType makeImpl(Class> rtype, Class>[] ptypes, boolean trusted) {
+ if (ptypes == null || ptypes.length == 0) {
+ ptypes = NO_PTYPES; trusted = true;
+ }
+ MethodType mt1 = new MethodType(rtype, ptypes);
+ MethodType mt0;
+ synchronized (internTable) {
+ mt0 = internTable.get(mt1);
+ if (mt0 != null)
+ return mt0;
+ }
+ if (!trusted)
+ // defensively copy the array passed in by the user
+ mt1 = new MethodType(rtype, ptypes.clone());
+ // promote the object to the Real Thing, and reprobe
+ MethodTypeForm form = MethodTypeForm.findForm(mt1);
+ mt1.form = form;
+ if (form.erasedType == mt1) {
+ // This is a principal (erased) type; show it to the JVM.
+ MethodHandleNatives.init(mt1);
+ }
+ synchronized (internTable) {
+ mt0 = internTable.get(mt1);
+ if (mt0 != null)
+ return mt0;
+ internTable.put(mt1, mt1);
+ }
+ return mt1;
+ }
+
+ private static final MethodType[] objectOnlyTypes = new MethodType[20];
+
+ /**
+ * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All parameters and the return type will be {@code Object},
+ * except the final varargs parameter if any, which will be {@code Object[]}.
+ * @param objectArgCount number of parameters (excluding the varargs parameter if any)
+ * @param varargs whether there will be a varargs parameter, of type {@code Object[]}
+ * @return a totally generic method type, given only its count of parameters and varargs
+ * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
+ * @see #genericMethodType(int)
+ */
+ public static
+ MethodType genericMethodType(int objectArgCount, boolean varargs) {
+ MethodType mt;
+ checkSlotCount(objectArgCount);
+ int ivarargs = (!varargs ? 0 : 1);
+ int ootIndex = objectArgCount*2 + ivarargs;
+ if (ootIndex < objectOnlyTypes.length) {
+ mt = objectOnlyTypes[ootIndex];
+ if (mt != null) return mt;
+ }
+ Class>[] ptypes = new Class>[objectArgCount + ivarargs];
+ Arrays.fill(ptypes, Object.class);
+ if (ivarargs != 0) ptypes[objectArgCount] = Object[].class;
+ mt = makeImpl(Object.class, ptypes, true);
+ if (ootIndex < objectOnlyTypes.length) {
+ objectOnlyTypes[ootIndex] = mt; // cache it here also!
+ }
+ return mt;
+ }
+
+ /**
+ * Finds or creates a method type whose components are all {@code Object}.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All parameters and the return type will be Object.
+ * @param objectArgCount number of parameters
+ * @return a totally generic method type, given only its count of parameters
+ * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
+ * @see #genericMethodType(int, boolean)
+ */
+ public static
+ MethodType genericMethodType(int objectArgCount) {
+ return genericMethodType(objectArgCount, false);
+ }
+
+ /**
+ * Finds or creates a method type with a single different parameter type.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param num the index (zero-based) of the parameter type to change
+ * @param nptype a new parameter type to replace the old one with
+ * @return the same type, except with the selected parameter changed
+ * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
+ * @throws IllegalArgumentException if {@code nptype} is {@code void.class}
+ * @throws NullPointerException if {@code nptype} is null
+ */
+ public MethodType changeParameterType(int num, Class> nptype) {
+ if (parameterType(num) == nptype) return this;
+ checkPtype(nptype);
+ Class>[] nptypes = ptypes.clone();
+ nptypes[num] = nptype;
+ return makeImpl(rtype, nptypes, true);
+ }
+
+ /**
+ * Finds or creates a method type with additional parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param num the position (zero-based) of the inserted parameter type(s)
+ * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+ * @return the same type, except with the selected parameter(s) inserted
+ * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ public MethodType insertParameterTypes(int num, Class>... ptypesToInsert) {
+ int len = ptypes.length;
+ if (num < 0 || num > len)
+ throw newIndexOutOfBoundsException(num);
+ int ins = checkPtypes(ptypesToInsert);
+ checkSlotCount(parameterSlotCount() + ptypesToInsert.length + ins);
+ int ilen = ptypesToInsert.length;
+ if (ilen == 0) return this;
+ Class>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+ilen);
+ System.arraycopy(nptypes, num, nptypes, num+ilen, len-num);
+ System.arraycopy(ptypesToInsert, 0, nptypes, num, ilen);
+ return makeImpl(rtype, nptypes, true);
+ }
+
+ /**
+ * Finds or creates a method type with additional parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
+ * @return the same type, except with the selected parameter(s) appended
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ public MethodType appendParameterTypes(Class>... ptypesToInsert) {
+ return insertParameterTypes(parameterCount(), ptypesToInsert);
+ }
+
+ /**
+ * Finds or creates a method type with additional parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param num the position (zero-based) of the inserted parameter type(s)
+ * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+ * @return the same type, except with the selected parameter(s) inserted
+ * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ public MethodType insertParameterTypes(int num, List> ptypesToInsert) {
+ return insertParameterTypes(num, ptypesToInsert.toArray(NO_PTYPES));
+ }
+
+ /**
+ * Finds or creates a method type with additional parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
+ * @return the same type, except with the selected parameter(s) appended
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ public MethodType appendParameterTypes(List> ptypesToInsert) {
+ return insertParameterTypes(parameterCount(), ptypesToInsert);
+ }
+
+ /**
+ * Finds or creates a method type with some parameter types omitted.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param start the index (zero-based) of the first parameter type to remove
+ * @param end the index (greater than {@code start}) of the first parameter type after not to remove
+ * @return the same type, except with the selected parameter(s) removed
+ * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
+ * or if {@code end} is negative or greater than {@code parameterCount()}
+ * or if {@code start} is greater than {@code end}
+ */
+ public MethodType dropParameterTypes(int start, int end) {
+ int len = ptypes.length;
+ if (!(0 <= start && start <= end && end <= len))
+ throw newIndexOutOfBoundsException("start="+start+" end="+end);
+ if (start == end) return this;
+ Class>[] nptypes;
+ if (start == 0) {
+ if (end == len) {
+ // drop all parameters
+ nptypes = NO_PTYPES;
+ } else {
+ // drop initial parameter(s)
+ nptypes = Arrays.copyOfRange(ptypes, end, len);
+ }
+ } else {
+ if (end == len) {
+ // drop trailing parameter(s)
+ nptypes = Arrays.copyOfRange(ptypes, 0, start);
+ } else {
+ int tail = len - end;
+ nptypes = Arrays.copyOfRange(ptypes, 0, start + tail);
+ System.arraycopy(ptypes, end, nptypes, start, tail);
+ }
+ }
+ return makeImpl(rtype, nptypes, true);
+ }
+
+ /**
+ * Finds or creates a method type with a different return type.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param nrtype a return parameter type to replace the old one with
+ * @return the same type, except with the return type change
+ * @throws NullPointerException if {@code nrtype} is null
+ */
+ public MethodType changeReturnType(Class> nrtype) {
+ if (returnType() == nrtype) return this;
+ return makeImpl(nrtype, ptypes, true);
+ }
+
+ /**
+ * Reports if this type contains a primitive argument or return value.
+ * The return type {@code void} counts as a primitive.
+ * @return true if any of the types are primitives
+ */
+ public boolean hasPrimitives() {
+ return form.hasPrimitives();
+ }
+
+ /**
+ * Reports if this type contains a wrapper argument or return value.
+ * Wrappers are types which box primitive values, such as {@link Integer}.
+ * The reference type {@code java.lang.Void} counts as a wrapper.
+ * @return true if any of the types are wrappers
+ */
+ public boolean hasWrappers() {
+ return unwrap() != this;
+ }
+
+ /**
+ * Erases all reference types to {@code Object}.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All primitive types (including {@code void}) will remain unchanged.
+ * @return a version of the original type with all reference types replaced
+ */
+ public MethodType erase() {
+ return form.erasedType();
+ }
+
+ /**
+ * Converts all types, both reference and primitive, to {@code Object}.
+ * Convenience method for {@link #genericMethodType(int) genericMethodType}.
+ * The expression {@code type.wrap().erase()} produces the same value
+ * as {@code type.generic()}.
+ * @return a version of the original type with all types replaced
+ */
+ public MethodType generic() {
+ return genericMethodType(parameterCount());
+ }
+
+ /**
+ * Converts all primitive types to their corresponding wrapper types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All reference types (including wrapper types) will remain unchanged.
+ * A {@code void} return type is changed to the type {@code java.lang.Void}.
+ * The expression {@code type.wrap().erase()} produces the same value
+ * as {@code type.generic()}.
+ * @return a version of the original type with all primitive types replaced
+ */
+ public MethodType wrap() {
+ return hasPrimitives() ? wrapWithPrims(this) : this;
+ }
+
+ /**
+ * Converts all wrapper types to their corresponding primitive types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All primitive types (including {@code void}) will remain unchanged.
+ * A return type of {@code java.lang.Void} is changed to {@code void}.
+ * @return a version of the original type with all wrapper types replaced
+ */
+ public MethodType unwrap() {
+ MethodType noprims = !hasPrimitives() ? this : wrapWithPrims(this);
+ return unwrapWithNoPrims(noprims);
+ }
+
+ private static MethodType wrapWithPrims(MethodType pt) {
+ assert(pt.hasPrimitives());
+ MethodType wt = pt.wrapAlt;
+ if (wt == null) {
+ // fill in lazily
+ wt = MethodTypeForm.canonicalize(pt, MethodTypeForm.WRAP, MethodTypeForm.WRAP);
+ assert(wt != null);
+ pt.wrapAlt = wt;
+ }
+ return wt;
+ }
+
+ private static MethodType unwrapWithNoPrims(MethodType wt) {
+ assert(!wt.hasPrimitives());
+ MethodType uwt = wt.wrapAlt;
+ if (uwt == null) {
+ // fill in lazily
+ uwt = MethodTypeForm.canonicalize(wt, MethodTypeForm.UNWRAP, MethodTypeForm.UNWRAP);
+ if (uwt == null)
+ uwt = wt; // type has no wrappers or prims at all
+ wt.wrapAlt = uwt;
+ }
+ return uwt;
+ }
+
+ /**
+ * Returns the parameter type at the specified index, within this method type.
+ * @param num the index (zero-based) of the desired parameter type
+ * @return the selected parameter type
+ * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
+ */
+ public Class> parameterType(int num) {
+ return ptypes[num];
+ }
+ /**
+ * Returns the number of parameter types in this method type.
+ * @return the number of parameter types
+ */
+ public int parameterCount() {
+ return ptypes.length;
+ }
+ /**
+ * Returns the return type of this method type.
+ * @return the return type
+ */
+ public Class> returnType() {
+ return rtype;
+ }
+
+ /**
+ * Presents the parameter types as a list (a convenience method).
+ * The list will be immutable.
+ * @return the parameter types (as an immutable list)
+ */
+ public List> parameterList() {
+ return Collections.unmodifiableList(Arrays.asList(ptypes));
+ }
+
+ /**
+ * Presents the parameter types as an array (a convenience method).
+ * Changes to the array will not result in changes to the type.
+ * @return the parameter types (as a fresh copy if necessary)
+ */
+ public Class>[] parameterArray() {
+ return ptypes.clone();
+ }
+
+ /**
+ * Compares the specified object with this type for equality.
+ * That is, it returns true if and only if the specified object
+ * is also a method type with exactly the same parameters and return type.
+ * @param x object to compare
+ * @see Object#equals(Object)
+ */
+ @Override
+ public boolean equals(Object x) {
+ return this == x || x instanceof MethodType && equals((MethodType)x);
+ }
+
+ private boolean equals(MethodType that) {
+ return this.rtype == that.rtype
+ && Arrays.equals(this.ptypes, that.ptypes);
+ }
+
+ /**
+ * Returns the hash code value for this method type.
+ * It is defined to be the same as the hashcode of a List
+ * whose elements are the return type followed by the
+ * parameter types.
+ * @return the hash code value for this method type
+ * @see Object#hashCode()
+ * @see #equals(Object)
+ * @see List#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ int hashCode = 31 + rtype.hashCode();
+ for (Class> ptype : ptypes)
+ hashCode = 31*hashCode + ptype.hashCode();
+ return hashCode;
+ }
+
+ /**
+ * Returns a string representation of the method type,
+ * of the form {@code "(PT0,PT1...)RT"}.
+ * The string representation of a method type is a
+ * parenthesis enclosed, comma separated list of type names,
+ * followed immediately by the return type.
+ *
+ * Each type is represented by its
+ * {@link java.lang.Class#getSimpleName simple name}.
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(");
+ for (int i = 0; i < ptypes.length; i++) {
+ if (i > 0) sb.append(",");
+ sb.append(ptypes[i].getSimpleName());
+ }
+ sb.append(")");
+ sb.append(rtype.getSimpleName());
+ return sb.toString();
+ }
+
+ /// Queries which have to do with the bytecode architecture
+
+ /** Reports the number of JVM stack slots required to invoke a method
+ * of this type. Note that (for historical reasons) the JVM requires
+ * a second stack slot to pass long and double arguments.
+ * So this method returns {@link #parameterCount() parameterCount} plus the
+ * number of long and double parameters (if any).
+ *
+ * This method is included for the benfit of applications that must
+ * generate bytecodes that process method handles and invokedynamic.
+ * @return the number of JVM stack slots for this type's parameters
+ */
+ /*non-public*/ int parameterSlotCount() {
+ return form.parameterSlotCount();
+ }
+
+ /*non-public*/ Invokers invokers() {
+ Invokers inv = invokers;
+ if (inv != null) return inv;
+ invokers = inv = new Invokers(this);
+ return inv;
+ }
+
+ /** Reports the number of JVM stack slots which carry all parameters including and after
+ * the given position, which must be in the range of 0 to
+ * {@code parameterCount} inclusive. Successive parameters are
+ * more shallowly stacked, and parameters are indexed in the bytecodes
+ * according to their trailing edge. Thus, to obtain the depth
+ * in the outgoing call stack of parameter {@code N}, obtain
+ * the {@code parameterSlotDepth} of its trailing edge
+ * at position {@code N+1}.
+ *
+ * Parameters of type {@code long} and {@code double} occupy
+ * two stack slots (for historical reasons) and all others occupy one.
+ * Therefore, the number returned is the number of arguments
+ * including and after the given parameter,
+ * plus the number of long or double arguments
+ * at or after after the argument for the given parameter.
+ *
+ * This method is included for the benfit of applications that must
+ * generate bytecodes that process method handles and invokedynamic.
+ * @param num an index (zero-based, inclusive) within the parameter types
+ * @return the index of the (shallowest) JVM stack slot transmitting the
+ * given parameter
+ * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
+ */
+ /*non-public*/ int parameterSlotDepth(int num) {
+ if (num < 0 || num > ptypes.length)
+ parameterType(num); // force a range check
+ return form.parameterToArgSlot(num-1);
+ }
+
+ /** Reports the number of JVM stack slots required to receive a return value
+ * from a method of this type.
+ * If the {@link #returnType() return type} is void, it will be zero,
+ * else if the return type is long or double, it will be two, else one.
+ *
+ * This method is included for the benfit of applications that must
+ * generate bytecodes that process method handles and invokedynamic.
+ * @return the number of JVM stack slots (0, 1, or 2) for this type's return value
+ * Will be removed for PFD.
+ */
+ /*non-public*/ int returnSlotCount() {
+ return form.returnSlotCount();
+ }
+
+ /**
+ * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * Any class or interface name embedded in the descriptor string
+ * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
+ * on the given loader (or if it is null, on the system class loader).
+ *
+ * Note that it is possible to encounter method types which cannot be
+ * constructed by this method, because their component types are
+ * not all reachable from a common class loader.
+ *
+ * This method is included for the benfit of applications that must
+ * generate bytecodes that process method handles and {@code invokedynamic}.
+ * @param descriptor a bytecode-level type descriptor string "(T...)T"
+ * @param loader the class loader in which to look up the types
+ * @return a method type matching the bytecode-level type descriptor
+ * @throws IllegalArgumentException if the string is not well-formed
+ * @throws TypeNotPresentException if a named type cannot be found
+ */
+ public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
+ throws IllegalArgumentException, TypeNotPresentException
+ {
+ List> types = BytecodeDescriptor.parseMethod(descriptor, loader);
+ Class> rtype = types.remove(types.size() - 1);
+ Class>[] ptypes = types.toArray(NO_PTYPES);
+ return makeImpl(rtype, ptypes, true);
+ }
+
+ /**
+ * Produces a bytecode descriptor representation of the method type.
+ *
+ * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
+ * Two distinct classes which share a common name but have different class loaders
+ * will appear identical when viewed within descriptor strings.
+ *
+ * This method is included for the benfit of applications that must
+ * generate bytecodes that process method handles and {@code invokedynamic}.
+ * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
+ * because the latter requires a suitable class loader argument.
+ * @return the bytecode type descriptor representation
+ */
+ public String toMethodDescriptorString() {
+ return BytecodeDescriptor.unparse(this);
+ }
+
+ /// Serialization.
+
+ /**
+ * There are no serializable fields for {@code MethodType}.
+ */
+ private static final java.io.ObjectStreamField[] serialPersistentFields = { };
+
+ /**
+ * Save the {@code MethodType} instance to a stream.
+ *
+ * @serialData
+ * For portability, the serialized format does not refer to named fields.
+ * Instead, the return type and parameter type arrays are written directly
+ * from the {@code writeObject} method, using two calls to {@code s.writeObject}
+ * as follows:
+ *
+s.writeObject(this.returnType());
+s.writeObject(this.parameterArray());
+ *
+ *
+ * The deserialized field values are checked as if they were
+ * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
+ * For example, null values, or {@code void} parameter types,
+ * will lead to exceptions during deserialization.
+ * @param the stream to write the object to
+ */
+ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+ s.defaultWriteObject(); // requires serialPersistentFields to be an empty array
+ s.writeObject(returnType());
+ s.writeObject(parameterArray());
+ }
+
+ /**
+ * Reconstitute the {@code MethodType} instance from a stream (that is,
+ * deserialize it).
+ * This instance is a scratch object with bogus final fields.
+ * It provides the parameters to the factory method called by
+ * {@link #readResolve readResolve}.
+ * After that call it is discarded.
+ * @param the stream to read the object from
+ * @see #MethodType()
+ * @see #readResolve
+ * @see #writeObject
+ */
+ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject(); // requires serialPersistentFields to be an empty array
+
+ Class> returnType = (Class>) s.readObject();
+ Class>[] parameterArray = (Class>[]) s.readObject();
+
+ // Probably this object will never escape, but let's check
+ // the field values now, just to be sure.
+ checkRtype(returnType);
+ checkPtypes(parameterArray);
+
+ parameterArray = parameterArray.clone(); // make sure it is unshared
+ MethodType_init(returnType, parameterArray);
+ }
+
+ /**
+ * For serialization only.
+ * Sets the final fields to null, pending {@code Unsafe.putObject}.
+ */
+ private MethodType() {
+ this.rtype = null;
+ this.ptypes = null;
+ }
+ private void MethodType_init(Class> rtype, Class>[] ptypes) {
+ // In order to communicate these values to readResolve, we must
+ // store them into the implementation-specific final fields.
+ checkRtype(rtype);
+ checkPtypes(ptypes);
+ unsafe.putObject(this, rtypeOffset, rtype);
+ unsafe.putObject(this, ptypesOffset, ptypes);
+ }
+
+ // Support for resetting final fields while deserializing
+ private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ private static final long rtypeOffset, ptypesOffset;
+ static {
+ try {
+ rtypeOffset = unsafe.objectFieldOffset
+ (MethodType.class.getDeclaredField("rtype"));
+ ptypesOffset = unsafe.objectFieldOffset
+ (MethodType.class.getDeclaredField("ptypes"));
+ } catch (Exception ex) {
+ throw new Error(ex);
+ }
+ }
+
+ /**
+ * Resolves and initializes a {@code MethodType} object
+ * after serialization.
+ * @return the fully initialized {@code MethodType} object
+ */
+ private Object readResolve() {
+ // Do not use a trusted path for deserialization:
+ //return makeImpl(rtype, ptypes, true);
+ // Verify all operands, and make sure ptypes is unshared:
+ return methodType(rtype, ptypes);
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.Wrapper;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * Shared information for a group of method types, which differ
+ * only by reference types, and therefore share a common erasure
+ * and wrapping.
+ *
+ * For an empirical discussion of the structure of method types,
+ * see
+ * the thread "Avoiding Boxing" on jvm-languages .
+ * There are approximately 2000 distinct erased method types in the JDK.
+ * There are a little over 10 times that number of unerased types.
+ * No more than half of these are likely to be loaded at once.
+ * @author John Rose
+ */
+class MethodTypeForm {
+ final int[] argToSlotTable, slotToArgTable;
+ final long argCounts; // packed slot & value counts
+ final long primCounts; // packed prim & double counts
+ final int vmslots; // total number of parameter slots
+ final MethodType erasedType; // the canonical erasure
+
+ /*lazy*/ MethodType primsAsBoxes; // replace prims by wrappers
+ /*lazy*/ MethodType primArgsAsBoxes; // wrap args only; make raw return
+ /*lazy*/ MethodType primsAsInts; // replace prims by int/long
+ /*lazy*/ MethodType primsAsLongs; // replace prims by long
+ /*lazy*/ MethodType primsAtEnd; // reorder primitives to the end
+
+ // Cached adapter information:
+ /*lazy*/ ToGeneric toGeneric; // convert cs. with prims to w/o
+ /*lazy*/ FromGeneric fromGeneric; // convert cs. w/o prims to with
+ /*lazy*/ SpreadGeneric[] spreadGeneric; // expand one argument to many
+ /*lazy*/ FilterGeneric filterGeneric; // convert argument(s) on the fly
+ /*lazy*/ MethodHandle genericInvoker; // hook for invokeGeneric
+
+ public MethodType erasedType() {
+ return erasedType;
+ }
+
+ protected MethodTypeForm(MethodType erasedType) {
+ this.erasedType = erasedType;
+
+ Class>[] ptypes = erasedType.ptypes();
+ int ptypeCount = ptypes.length;
+ int pslotCount = ptypeCount; // temp. estimate
+ int rtypeCount = 1; // temp. estimate
+ int rslotCount = 1; // temp. estimate
+
+ int[] argToSlotTab = null, slotToArgTab = null;
+
+ // Walk the argument types, looking for primitives.
+ int pac = 0, lac = 0, prc = 0, lrc = 0;
+ Class> epts[] = ptypes;
+ for (int i = 0; i < epts.length; i++) {
+ Class> pt = epts[i];
+ if (pt != Object.class) {
+ assert(pt.isPrimitive());
+ ++pac;
+ if (hasTwoArgSlots(pt)) ++lac;
+ }
+ }
+ pslotCount += lac; // #slots = #args + #longs
+ Class> rt = erasedType.returnType();
+ if (rt != Object.class) {
+ ++prc; // even void.class counts as a prim here
+ if (hasTwoArgSlots(rt)) ++lrc;
+ // adjust #slots, #args
+ if (rt == void.class)
+ rtypeCount = rslotCount = 0;
+ else
+ rslotCount += lrc;
+ }
+ if (lac != 0) {
+ int slot = ptypeCount + lac;
+ slotToArgTab = new int[slot+1];
+ argToSlotTab = new int[1+ptypeCount];
+ argToSlotTab[0] = slot; // argument "-1" is past end of slots
+ for (int i = 0; i < epts.length; i++) {
+ Class> pt = epts[i];
+ if (hasTwoArgSlots(pt)) --slot;
+ --slot;
+ slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
+ argToSlotTab[1+i] = slot;
+ }
+ assert(slot == 0); // filled the table
+ }
+ this.primCounts = pack(lrc, prc, lac, pac);
+ this.argCounts = pack(rslotCount, rtypeCount, pslotCount, ptypeCount);
+ if (slotToArgTab == null) {
+ int slot = ptypeCount; // first arg is deepest in stack
+ slotToArgTab = new int[slot+1];
+ argToSlotTab = new int[1+ptypeCount];
+ argToSlotTab[0] = slot; // argument "-1" is past end of slots
+ for (int i = 0; i < ptypeCount; i++) {
+ --slot;
+ slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
+ argToSlotTab[1+i] = slot;
+ }
+ }
+ this.argToSlotTable = argToSlotTab;
+ this.slotToArgTable = slotToArgTab;
+
+ if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments");
+
+ // send a few bits down to the JVM:
+ this.vmslots = parameterSlotCount();
+
+ // short circuit some no-op canonicalizations:
+ if (!hasPrimitives()) {
+ primsAsBoxes = erasedType;
+ primArgsAsBoxes = erasedType;
+ primsAsInts = erasedType;
+ primsAsLongs = erasedType;
+ primsAtEnd = erasedType;
+ }
+ }
+
+ /** Turn all primitive types to corresponding wrapper types.
+ */
+ public MethodType primsAsBoxes() {
+ MethodType ct = primsAsBoxes;
+ if (ct != null) return ct;
+ MethodType t = erasedType;
+ ct = canonicalize(erasedType, WRAP, WRAP);
+ if (ct == null) ct = t; // no prims to box
+ return primsAsBoxes = ct;
+ }
+
+ /** Turn all primitive argument types to corresponding wrapper types.
+ * Subword and void return types are promoted to int.
+ */
+ public MethodType primArgsAsBoxes() {
+ MethodType ct = primArgsAsBoxes;
+ if (ct != null) return ct;
+ MethodType t = erasedType;
+ ct = canonicalize(erasedType, RAW_RETURN, WRAP);
+ if (ct == null) ct = t; // no prims to box
+ return primArgsAsBoxes = ct;
+ }
+
+ /** Turn all primitive types to either int or long.
+ * Floating point return types are not changed, because
+ * they may require special calling sequences.
+ * A void return value is turned to int.
+ */
+ public MethodType primsAsInts() {
+ MethodType ct = primsAsInts;
+ if (ct != null) return ct;
+ MethodType t = erasedType;
+ ct = canonicalize(t, RAW_RETURN, INTS);
+ if (ct == null) ct = t; // no prims to int-ify
+ return primsAsInts = ct;
+ }
+
+ /** Turn all primitive types to either int or long.
+ * Floating point return types are not changed, because
+ * they may require special calling sequences.
+ * A void return value is turned to int.
+ */
+ public MethodType primsAsLongs() {
+ MethodType ct = primsAsLongs;
+ if (ct != null) return ct;
+ MethodType t = erasedType;
+ ct = canonicalize(t, RAW_RETURN, LONGS);
+ if (ct == null) ct = t; // no prims to int-ify
+ return primsAsLongs = ct;
+ }
+
+ /** Stably sort parameters into 3 buckets: ref, int, long. */
+ public MethodType primsAtEnd() {
+ MethodType ct = primsAtEnd;
+ if (ct != null) return ct;
+ MethodType t = erasedType;
+
+ int pac = primitiveParameterCount();
+ if (pac == 0)
+ return primsAtEnd = t;
+
+ int argc = parameterCount();
+ int lac = longPrimitiveParameterCount();
+ if (pac == argc && (lac == 0 || lac == argc))
+ return primsAtEnd = t;
+
+ // known to have a mix of 2 or 3 of ref, int, long
+ int[] reorder = primsAtEndOrder(t);
+ ct = reorderParameters(t, reorder, null);
+ //System.out.println("t="+t+" / reorder="+java.util.Arrays.toString(reorder)+" => "+ct);
+ return primsAtEnd = ct;
+ }
+
+ /** Compute a new ordering of parameters so that all references
+ * are before all ints or longs, and all ints are before all longs.
+ * For this ordering, doubles count as longs, and all other primitive
+ * values count as ints.
+ * As a special case, if the parameters are already in the specified
+ * order, this method returns a null reference, rather than an array
+ * specifying a null permutation.
+ *
+ * For example, the type {@code (int,boolean,int,Object,String)void}
+ * produces the order {@code {3,4,0,1,2}}, the type
+ * {@code (long,int,String)void} produces {@code {2,1,2}}, and
+ * the type {@code (Object,int)Object} produces {@code null}.
+ */
+ public static int[] primsAtEndOrder(MethodType mt) {
+ MethodTypeForm form = mt.form();
+ if (form.primsAtEnd == form.erasedType)
+ // quick check shows no reordering is necessary
+ return null;
+
+ int argc = form.parameterCount();
+ int[] paramOrder = new int[argc];
+
+ // 3-way bucket sort:
+ int pac = form.primitiveParameterCount();
+ int lac = form.longPrimitiveParameterCount();
+ int rfill = 0, ifill = argc - pac, lfill = argc - lac;
+
+ Class>[] ptypes = mt.ptypes();
+ boolean changed = false;
+ for (int i = 0; i < ptypes.length; i++) {
+ Class> pt = ptypes[i];
+ int ord;
+ if (!pt.isPrimitive()) ord = rfill++;
+ else if (!hasTwoArgSlots(pt)) ord = ifill++;
+ else ord = lfill++;
+ if (ord != i) changed = true;
+ assert(paramOrder[ord] == 0);
+ paramOrder[ord] = i;
+ }
+ assert(rfill == argc - pac && ifill == argc - lac && lfill == argc);
+ if (!changed) {
+ form.primsAtEnd = form.erasedType;
+ return null;
+ }
+ return paramOrder;
+ }
+
+ /** Put the existing parameters of mt into a new order, given by newParamOrder.
+ * The third argument is logically appended to mt.parameterArray,
+ * so that elements of newParamOrder can index either pre-existing or
+ * new parameter types.
+ */
+ public static MethodType reorderParameters(MethodType mt, int[] newParamOrder, Class>[] moreParams) {
+ if (newParamOrder == null) return mt; // no-op reordering
+ Class>[] ptypes = mt.ptypes();
+ Class>[] ntypes = new Class>[newParamOrder.length];
+ int maxParam = ptypes.length + (moreParams == null ? 0 : moreParams.length);
+ boolean changed = (ntypes.length != ptypes.length);
+ for (int i = 0; i < newParamOrder.length; i++) {
+ int param = newParamOrder[i];
+ if (param != i) changed = true;
+ Class> nt;
+ if (param < ptypes.length) nt = ptypes[param];
+ else if (param == maxParam) nt = mt.returnType();
+ else nt = moreParams[param - ptypes.length];
+ ntypes[i] = nt;
+ }
+ if (!changed) return mt;
+ return MethodType.makeImpl(mt.returnType(), ntypes, true);
+ }
+
+ private static boolean hasTwoArgSlots(Class> type) {
+ return type == long.class || type == double.class;
+ }
+
+ private static long pack(int a, int b, int c, int d) {
+ assert(((a|b|c|d) & ~0xFFFF) == 0);
+ long hw = ((a << 16) | b), lw = ((c << 16) | d);
+ return (hw << 32) | lw;
+ }
+ private static char unpack(long packed, int word) { // word==0 => return a, ==3 => return d
+ assert(word <= 3);
+ return (char)(packed >> ((3-word) * 16));
+ }
+
+ public int parameterCount() { // # outgoing values
+ return unpack(argCounts, 3);
+ }
+ public int parameterSlotCount() { // # outgoing interpreter slots
+ return unpack(argCounts, 2);
+ }
+ public int returnCount() { // = 0 (V), or 1
+ return unpack(argCounts, 1);
+ }
+ public int returnSlotCount() { // = 0 (V), 2 (J/D), or 1
+ return unpack(argCounts, 0);
+ }
+ public int primitiveParameterCount() {
+ return unpack(primCounts, 3);
+ }
+ public int longPrimitiveParameterCount() {
+ return unpack(primCounts, 2);
+ }
+ public int primitiveReturnCount() { // = 0 (obj), or 1
+ return unpack(primCounts, 1);
+ }
+ public int longPrimitiveReturnCount() { // = 1 (J/D), or 0
+ return unpack(primCounts, 0);
+ }
+ public boolean hasPrimitives() {
+ return primCounts != 0;
+ }
+// public boolean hasNonVoidPrimitives() {
+// if (primCounts == 0) return false;
+// if (primitiveParameterCount() != 0) return true;
+// return (primitiveReturnCount() != 0 && returnCount() != 0);
+// }
+ public boolean hasLongPrimitives() {
+ return (longPrimitiveParameterCount() | longPrimitiveReturnCount()) != 0;
+ }
+ public int parameterToArgSlot(int i) {
+ return argToSlotTable[1+i];
+ }
+ public int argSlotToParameter(int argSlot) {
+ // Note: Empty slots are represented by zero in this table.
+ // Valid arguments slots contain incremented entries, so as to be non-zero.
+ // We return -1 the caller to mean an empty slot.
+ return slotToArgTable[argSlot] - 1;
+ }
+
+ static MethodTypeForm findForm(MethodType mt) {
+ MethodType erased = canonicalize(mt, ERASE, ERASE);
+ if (erased == null) {
+ // It is already erased. Make a new MethodTypeForm.
+ return new MethodTypeForm(mt);
+ } else {
+ // Share the MethodTypeForm with the erased version.
+ return erased.form();
+ }
+ }
+
+ /** Codes for {@link #canonicalize(java.lang.Class, int)}.
+ * ERASE means change every reference to {@code Object}.
+ * WRAP means convert primitives (including {@code void} to their
+ * corresponding wrapper types. UNWRAP means the reverse of WRAP.
+ * INTS means convert all non-void primitive types to int or long,
+ * according to size. LONGS means convert all non-void primitives
+ * to long, regardless of size. RAW_RETURN means convert a type
+ * (assumed to be a return type) to int if it is smaller than an int,
+ * or if it is void.
+ */
+ public static final int NO_CHANGE = 0, ERASE = 1, WRAP = 2, UNWRAP = 3, INTS = 4, LONGS = 5, RAW_RETURN = 6;
+
+ /** Canonicalize the types in the given method type.
+ * If any types change, intern the new type, and return it.
+ * Otherwise return null.
+ */
+ public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) {
+ Class>[] ptypes = mt.ptypes();
+ Class>[] ptc = MethodTypeForm.canonicalizes(ptypes, howArgs);
+ Class> rtype = mt.returnType();
+ Class> rtc = MethodTypeForm.canonicalize(rtype, howRet);
+ if (ptc == null && rtc == null) {
+ // It is already canonical.
+ return null;
+ }
+ // Find the erased version of the method type:
+ if (rtc == null) rtc = rtype;
+ if (ptc == null) ptc = ptypes;
+ return MethodType.makeImpl(rtc, ptc, true);
+ }
+
+ /** Canonicalize the given return or param type.
+ * Return null if the type is already canonicalized.
+ */
+ static Class> canonicalize(Class> t, int how) {
+ Class> ct;
+ if (t == Object.class) {
+ // no change, ever
+ } else if (!t.isPrimitive()) {
+ switch (how) {
+ case UNWRAP:
+ ct = Wrapper.asPrimitiveType(t);
+ if (ct != t) return ct;
+ break;
+ case RAW_RETURN:
+ case ERASE:
+ return Object.class;
+ }
+ } else if (t == void.class) {
+ // no change, usually
+ switch (how) {
+ case RAW_RETURN:
+ return int.class;
+ case WRAP:
+ return Void.class;
+ }
+ } else {
+ // non-void primitive
+ switch (how) {
+ case WRAP:
+ return Wrapper.asWrapperType(t);
+ case INTS:
+ if (t == int.class || t == long.class)
+ return null; // no change
+ if (t == double.class)
+ return long.class;
+ return int.class;
+ case LONGS:
+ if (t == long.class)
+ return null; // no change
+ return long.class;
+ case RAW_RETURN:
+ if (t == int.class || t == long.class ||
+ t == float.class || t == double.class)
+ return null; // no change
+ // everything else returns as an int
+ return int.class;
+ }
+ }
+ // no change; return null to signify
+ return null;
+ }
+
+ /** Canonicalize each param type in the given array.
+ * Return null if all types are already canonicalized.
+ */
+ static Class>[] canonicalizes(Class>[] ts, int how) {
+ Class>[] cs = null;
+ for (int imax = ts.length, i = 0; i < imax; i++) {
+ Class> c = canonicalize(ts[i], how);
+ if (c != null) {
+ if (cs == null)
+ cs = ts.clone();
+ cs[i] = c;
+ }
+ }
+ return cs;
+ }
+
+ /*non-public*/ void notifyGenericMethodType() {
+ if (genericInvoker != null) return;
+ try {
+ // Trigger adapter creation.
+ genericInvoker = InvokeGeneric.genericInvokerOf(erasedType);
+ } catch (Exception ex) {
+ Error err = new InternalError("Exception while resolving invokeGeneric");
+ err.initCause(ex);
+ throw err;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Form"+erasedType;
+ }
+
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/MutableCallSite.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/MutableCallSite.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A {@code MutableCallSite} is a {@link CallSite} whose target variable
+ * behaves like an ordinary field.
+ * An {@code invokedynamic} instruction linked to a {@code MutableCallSite} delegates
+ * all calls to the site's current target.
+ * The {@linkplain CallSite#dynamicInvoker dynamic invoker} of a mutable call site
+ * also delegates each call to the site's current target.
+ *
+ * Here is an example of a mutable call site which introduces a
+ * state variable into a method handle chain.
+ *
+MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
+MethodHandle MH_name = name.dynamicInvoker();
+MethodType MT_str2 = MethodType.methodType(String.class, String.class);
+MethodHandle MH_upcase = MethodHandles.lookup()
+ .findVirtual(String.class, "toUpperCase", MT_str2);
+MethodHandle worker1 = MethodHandles.filterReturnValue(MH_name, MH_upcase);
+name.setTarget(MethodHandles.constant(String.class, "Rocky"));
+assertEquals("ROCKY", (String) worker1.invokeExact());
+name.setTarget(MethodHandles.constant(String.class, "Fred"));
+assertEquals("FRED", (String) worker1.invokeExact());
+// (mutation can be continued indefinitely)
+ *
+ *
+ * The same call site may be used in several places at once.
+ *
+MethodHandle MH_dear = MethodHandles.lookup()
+ .findVirtual(String.class, "concat", MT_str2).bindTo(", dear?");
+MethodHandle worker2 = MethodHandles.filterReturnValue(MH_name, MH_dear);
+assertEquals("Fred, dear?", (String) worker2.invokeExact());
+name.setTarget(MethodHandles.constant(String.class, "Wilma"));
+assertEquals("WILMA", (String) worker1.invokeExact());
+assertEquals("Wilma, dear?", (String) worker2.invokeExact());
+ *
+ *
+ * Non-synchronization of target values:
+ * A write to a mutable call site's target does not force other threads
+ * to become aware of the updated value. Threads which do not perform
+ * suitable synchronization actions relative to the updated call site
+ * may cache the old target value and delay their use of the new target
+ * value indefinitely.
+ * (This is a normal consequence of the Java Memory Model as applied
+ * to object fields.)
+ *
+ * The {@link #syncAll syncAll} operation provides a way to force threads
+ * to accept a new target value, even if there is no other synchronization.
+ *
+ * For target values which will be frequently updated, consider using
+ * a {@linkplain VolatileCallSite volatile call site} instead.
+ * @author John Rose, JSR 292 EG
+ */
+public class MutableCallSite extends CallSite {
+ /**
+ * Creates a blank call site object with the given method type.
+ * The initial target is set to a method handle of the given type
+ * which will throw an {@link IllegalStateException} if called.
+ *
+ * The type of the call site is permanently set to the given type.
+ *
+ * Before this {@code CallSite} object is returned from a bootstrap method,
+ * or invoked in some other manner,
+ * it is usually provided with a more useful target method,
+ * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
+ * @param type the method type that this call site will have
+ * @throws NullPointerException if the proposed type is null
+ */
+ public MutableCallSite(MethodType type) {
+ super(type);
+ }
+
+ /**
+ * Creates a call site object with an initial target method handle.
+ * The type of the call site is permanently set to the initial target's type.
+ * @param target the method handle that will be the initial target of the call site
+ * @throws NullPointerException if the proposed target is null
+ */
+ public MutableCallSite(MethodHandle target) {
+ super(target);
+ }
+
+ /**
+ * Returns the target method of the call site, which behaves
+ * like a normal field of the {@code MutableCallSite}.
+ *
+ * The interactions of {@code getTarget} with memory are the same
+ * as of a read from an ordinary variable, such as an array element or a
+ * non-volatile, non-final field.
+ *
+ * In particular, the current thread may choose to reuse the result
+ * of a previous read of the target from memory, and may fail to see
+ * a recent update to the target by another thread.
+ *
+ * @return the linkage state of this call site, a method handle which can change over time
+ * @see #setTarget
+ */
+ @Override public final MethodHandle getTarget() {
+ return target;
+ }
+
+ /**
+ * Updates the target method of this call site, as a normal variable.
+ * The type of the new target must agree with the type of the old target.
+ *
+ * The interactions with memory are the same
+ * as of a write to an ordinary variable, such as an array element or a
+ * non-volatile, non-final field.
+ *
+ * In particular, unrelated threads may fail to see the updated target
+ * until they perform a read from memory.
+ * Stronger guarantees can be created by putting appropriate operations
+ * into the bootstrap method and/or the target methods used
+ * at any given call site.
+ *
+ * @param newTarget the new target
+ * @throws NullPointerException if the proposed new target is null
+ * @throws WrongMethodTypeException if the proposed new target
+ * has a method type that differs from the previous target
+ * @see #getTarget
+ */
+ @Override public void setTarget(MethodHandle newTarget) {
+ checkTargetChange(this.target, newTarget);
+ setTargetNormal(newTarget);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final MethodHandle dynamicInvoker() {
+ return makeDynamicInvoker();
+ }
+
+ /**
+ * Performs a synchronization operation on each call site in the given array,
+ * forcing all other threads to throw away any cached values previously
+ * loaded from the target of any of the call sites.
+ *
+ * This operation does not reverse any calls that have already started
+ * on an old target value.
+ * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
+ *
+ * The overall effect is to force all future readers of each call site's target
+ * to accept the most recently stored value.
+ * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
+ * Conversely, the {@code syncAll} call may block until all readers have
+ * (somehow) decached all previous versions of each call site's target.
+ *
+ * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
+ * should generally be performed under some sort of mutual exclusion.
+ * Note that reader threads may observe an updated target as early
+ * as the {@code setTarget} call that install the value
+ * (and before the {@code syncAll} that confirms the value).
+ * On the other hand, reader threads may observe previous versions of
+ * the target until the {@code syncAll} call returns
+ * (and after the {@code setTarget} that attempts to convey the updated version).
+ *
+ * This operation is likely to be expensive and should be used sparingly.
+ * If possible, it should be buffered for batch processing on sets of call sites.
+ *
+ * If {@code sites} contains a null element,
+ * a {@code NullPointerException} will be raised.
+ * In this case, some non-null elements in the array may be
+ * processed before the method returns abnormally.
+ * Which elements these are (if any) is implementation-dependent.
+ *
+ *
Java Memory Model details
+ * In terms of the Java Memory Model, this operation performs a synchronization
+ * action which is comparable in effect to the writing of a volatile variable
+ * by the current thread, and an eventual volatile read by every other thread
+ * that may access one of the affected call sites.
+ *
+ * The following effects are apparent, for each individual call site {@code S}:
+ *
+ * A new volatile variable {@code V} is created, and written by the current thread.
+ * As defined by the JMM, this write is a global synchronization event.
+ * As is normal with thread-local ordering of write events,
+ * every action already performed by the current thread is
+ * taken to happen before the volatile write to {@code V}.
+ * (In some implementations, this means that the current thread
+ * performs a global release operation.)
+ * Specifically, the write to the current target of {@code S} is
+ * taken to happen before the volatile write to {@code V}.
+ * The volatile write to {@code V} is placed
+ * (in an implementation specific manner)
+ * in the global synchronization order.
+ * Consider an arbitrary thread {@code T} (other than the current thread).
+ * If {@code T} executes a synchronization action {@code A}
+ * after the volatile write to {@code V} (in the global synchronization order),
+ * it is therefore required to see either the current target
+ * of {@code S}, or a later write to that target,
+ * if it executes a read on the target of {@code S}.
+ * (This constraint is called "synchronization-order consistency".)
+ * The JMM specifically allows optimizing compilers to elide
+ * reads or writes of variables that are known to be useless.
+ * Such elided reads and writes have no effect on the happens-before
+ * relation. Regardless of this fact, the volatile {@code V}
+ * will not be elided, even though its written value is
+ * indeterminate and its read value is not used.
+ *
+ * Because of the last point, the implementation behaves as if a
+ * volatile read of {@code V} were performed by {@code T}
+ * immediately after its action {@code A}. In the local ordering
+ * of actions in {@code T}, this read happens before any future
+ * read of the target of {@code S}. It is as if the
+ * implementation arbitrarily picked a read of {@code S}'s target
+ * by {@code T}, and forced a read of {@code V} to precede it,
+ * thereby ensuring communication of the new target value.
+ *
+ * As long as the constraints of the Java Memory Model are obeyed,
+ * implementations may delay the completion of a {@code syncAll}
+ * operation while other threads ({@code T} above) continue to
+ * use previous values of {@code S}'s target.
+ * However, implementations are (as always) encouraged to avoid
+ * livelock, and to eventually require all threads to take account
+ * of the updated target.
+ *
+ *
+ * Discussion:
+ * For performance reasons, {@code syncAll} is not a virtual method
+ * on a single call site, but rather applies to a set of call sites.
+ * Some implementations may incur a large fixed overhead cost
+ * for processing one or more synchronization operations,
+ * but a small incremental cost for each additional call site.
+ * In any case, this operation is likely to be costly, since
+ * other threads may have to be somehow interrupted
+ * in order to make them notice the updated target value.
+ * However, it may be observed that a single call to synchronize
+ * several sites has the same formal effect as many calls,
+ * each on just one of the sites.
+ *
+ *
+ * Implementation Note:
+ * Simple implementations of {@code MutableCallSite} may use
+ * a volatile variable for the target of a mutable call site.
+ * In such an implementation, the {@code syncAll} method can be a no-op,
+ * and yet it will conform to the JMM behavior documented above.
+ *
+ * @param sites an array of call sites to be synchronized
+ * @throws NullPointerException if the {@code sites} array reference is null
+ * or the array contains a null
+ */
+ public static void syncAll(MutableCallSite[] sites) {
+ if (sites.length == 0) return;
+ STORE_BARRIER.lazySet(0);
+ for (int i = 0; i < sites.length; i++) {
+ sites[i].getClass(); // trigger NPE on first null
+ }
+ // FIXME: NYI
+ }
+ private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/SpreadGeneric.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/SpreadGeneric.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,678 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.ValueConversions;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * Generic spread adapter.
+ * Expands a final argument into multiple (zero or more) arguments, keeping the others the same.
+ * @author jrose
+ */
+class SpreadGeneric {
+ // type for the outgoing call
+ private final MethodType targetType;
+ // number of arguments to spread
+ private final int spreadCount;
+ // prototype adapter (clone and customize for each new target!)
+ private final Adapter adapter;
+ // entry point for adapter (Adapter mh, a...) => ...
+ private final MethodHandle entryPoint;
+
+ /** Compute and cache information common to all spreading adapters
+ * that accept calls of the given (generic) type.
+ */
+ private SpreadGeneric(MethodType targetType, int spreadCount) {
+ assert(targetType == targetType.generic());
+ this.targetType = targetType;
+ this.spreadCount = spreadCount;
+ // the target invoker will generally need casts on reference arguments
+ MethodHandle[] ep = { null };
+ Adapter ad = findAdapter(this, ep);
+ if (ad != null) {
+ this.adapter = ad;
+ this.entryPoint = ep[0];
+ return;
+ }
+ this.adapter = buildAdapterFromBytecodes(targetType, spreadCount, ep);
+ this.entryPoint = ep[0];
+ }
+
+ /** From targetType remove the last spreadCount arguments, and instead
+ * append a simple Object argument.
+ */
+ static MethodType preSpreadType(MethodType targetType, int spreadCount) {
+ @SuppressWarnings("unchecked")
+ ArrayList> params = new ArrayList(targetType.parameterList());
+ int outargs = params.size();
+ params.subList(outargs - spreadCount, outargs).clear();
+ params.add(Object.class);
+ return MethodType.methodType(targetType.returnType(), params);
+ }
+
+ MethodHandle makeInstance(MethodHandle target) {
+ MethodType type = target.type();
+ if (type != targetType) {
+ throw new UnsupportedOperationException("NYI type="+type);
+ }
+ return adapter.makeInstance(this, target);
+ }
+
+ /** Build an adapter of the given generic type, which invokes typedTarget
+ * on the incoming arguments, after unboxing as necessary.
+ * The return value is boxed if necessary.
+ * @param genericType the required type of the result
+ * @param typedTarget the target
+ * @return an adapter method handle
+ */
+ public static MethodHandle make(MethodHandle target, int spreadCount) {
+ MethodType type = target.type();
+ MethodType gtype = type.generic();
+ if (type == gtype) {
+ return SpreadGeneric.of(type, spreadCount).makeInstance(target);
+ } else {
+ MethodHandle gtarget = FromGeneric.make(target);
+ assert(gtarget.type() == gtype);
+ MethodHandle gspread = SpreadGeneric.of(gtype, spreadCount).makeInstance(gtarget);
+ return ToGeneric.make(preSpreadType(type, spreadCount), gspread);
+ }
+ }
+
+ /** Return the adapter information for this type's erasure. */
+ static SpreadGeneric of(MethodType targetType, int spreadCount) {
+ if (targetType != targetType.generic())
+ throw new UnsupportedOperationException("NYI type="+targetType);
+ MethodTypeForm form = targetType.form();
+ int outcount = form.parameterCount();
+ assert(spreadCount <= outcount);
+ SpreadGeneric[] spreadGens = form.spreadGeneric;
+ if (spreadGens == null)
+ form.spreadGeneric = spreadGens = new SpreadGeneric[outcount+1];
+ SpreadGeneric spreadGen = spreadGens[spreadCount];
+ if (spreadGen == null)
+ spreadGens[spreadCount] = spreadGen = new SpreadGeneric(form.erasedType(), spreadCount);
+ return spreadGen;
+ }
+
+ public String toString() {
+ return getClass().getSimpleName()+targetType+"["+spreadCount+"]";
+ }
+
+ // This mini-api is called from an Adapter to manage the spread.
+ /** A check/coercion that happens once before any selections. */
+ protected Object check(Object av, int n) {
+ checkSpreadArgument(av, n);
+ return av;
+ }
+
+ /** The selection operator for spreading; note that it takes Object not Object[]. */
+ protected Object select(Object av, int n) {
+ return ((Object[])av)[n];
+ }
+ /*
+ protected int select_I(Object av, int n) {
+ // maybe return ((int[])select)[n]
+ throw new UnsupportedOperationException("subclass resp.");
+ }
+ protected int select_J(Object av, int n) {
+ // maybe return ((long[])select)[n]
+ throw new UnsupportedOperationException("subclass resp.");
+ }
+ // */
+
+ /* Create an adapter that handles spreading calls for the given type. */
+ static Adapter findAdapter(SpreadGeneric outer, MethodHandle[] ep) {
+ MethodType targetType = outer.targetType;
+ int spreadCount = outer.spreadCount;
+ int outargs = targetType.parameterCount();
+ int inargs = outargs - spreadCount;
+ if (inargs < 0) return null;
+ MethodType entryType = MethodType.genericMethodType(inargs + 1); // 1 for av
+ String cname1 = "S" + outargs;
+ String[] cnames = { cname1 };
+ String iname = "invoke_S"+spreadCount;
+ // e.g., D5I2, D5, L5I2, L5; invoke_D5
+ for (String cname : cnames) {
+ Class extends Adapter> acls = Adapter.findSubClass(cname);
+ if (acls == null) continue;
+ // see if it has the required invoke method
+ MethodHandle entryPoint = null;
+ try {
+ entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
+ } catch (ReflectiveOperationException ex) {
+ }
+ if (entryPoint == null) continue;
+ Constructor extends Adapter> ctor = null;
+ try {
+ ctor = acls.getDeclaredConstructor(SpreadGeneric.class);
+ } catch (NoSuchMethodException ex) {
+ } catch (SecurityException ex) {
+ }
+ if (ctor == null) continue;
+ try {
+ // Produce an instance configured as a prototype.
+ Adapter ad = ctor.newInstance(outer);
+ ep[0] = entryPoint;
+ return ad;
+ } catch (IllegalArgumentException ex) {
+ } catch (InvocationTargetException wex) {
+ Throwable ex = wex.getTargetException();
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ } catch (InstantiationException ex) {
+ } catch (IllegalAccessException ex) {
+ }
+ }
+ return null;
+ }
+
+ static Adapter buildAdapterFromBytecodes(MethodType targetType,
+ int spreadCount, MethodHandle[] ep) {
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ /**
+ * This adapter takes some untyped arguments, and returns an untyped result.
+ * Internally, it applies the invoker to the target, which causes the
+ * objects to be unboxed; the result is a raw type in L/I/J/F/D.
+ * This result is passed to convert, which is responsible for
+ * converting the raw result into a boxed object.
+ * The invoker is kept separate from the target because it can be
+ * generated once per type erasure family, and reused across adapters.
+ */
+ static abstract class Adapter extends BoundMethodHandle {
+ /*
+ * class X<> extends Adapter {
+ * (Object**N)=>R target;
+ * static int S = N-M;
+ * Object invoke(Object**M a, Object v) = target(a..., v[0]...v[S-1]);
+ * }
+ */
+ protected final SpreadGeneric outer;
+ protected final MethodHandle target; // (any**N) => R
+
+ @Override
+ public String toString() {
+ return addTypeString(target, this);
+ }
+
+ static final MethodHandle NO_ENTRY = ValueConversions.identity();
+
+ protected boolean isPrototype() { return target == null; }
+ protected Adapter(SpreadGeneric outer) {
+ super(NO_ENTRY);
+ this.outer = outer;
+ this.target = null;
+ assert(isPrototype());
+ }
+
+ protected Adapter(SpreadGeneric outer, MethodHandle target) {
+ super(outer.entryPoint);
+ this.outer = outer;
+ this.target = target;
+ }
+
+ /** Make a copy of self, with new fields. */
+ protected abstract Adapter makeInstance(SpreadGeneric outer, MethodHandle target);
+ // { return new ThisType(outer, target); }
+
+ protected Object check(Object av, int n) {
+ return outer.check(av, n);
+ }
+ protected Object select(Object av, int n) {
+ return outer.select(av, n);
+ }
+
+ static private final String CLASS_PREFIX; // "java.lang.invoke.SpreadGeneric$"
+ static {
+ String aname = Adapter.class.getName();
+ String sname = Adapter.class.getSimpleName();
+ if (!aname.endsWith(sname)) throw new InternalError();
+ CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
+ }
+ /** Find a sibing class of Adapter. */
+ static Class extends Adapter> findSubClass(String name) {
+ String cname = Adapter.CLASS_PREFIX + name;
+ try {
+ return Class.forName(cname).asSubclass(Adapter.class);
+ } catch (ClassNotFoundException ex) {
+ return null;
+ } catch (ClassCastException ex) {
+ return null;
+ }
+ }
+ }
+
+ /* generated classes follow this pattern:
+ static class xS2 extends Adapter {
+ protected xS2(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected xS2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected xS2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new xS2(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av,0);
+ return target.invokeExact(a0, a1)); }
+ protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av,1);
+ return target.invokeExact(a0,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av,1);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1)); }
+ }
+ // */
+
+/*
+: SHELL; n=SpreadGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
+//{{{
+import java.util.*;
+class genclasses {
+ static String[][] TEMPLATES = { {
+ "@for@ N=0..10",
+ " //@each-cat@",
+ " static class @cat@ extends Adapter {",
+ " protected @cat@(SpreadGeneric outer) { super(outer); } // to build prototype",
+ " protected @cat@(SpreadGeneric outer, MethodHandle t) { super(outer, t); }",
+ " protected @cat@ makeInstance(SpreadGeneric outer, MethodHandle t) { return new @cat@(outer, t); }",
+ " protected Object invoke_S0(@Tvav,@Object av) throws Throwable { av = super.check(av, 0);",
+ " return target.invokeExact(@av@); }",
+ " //@each-S@",
+ " protected Object invoke_S@S@(@Tvav,@Object av) throws Throwable { av = super.check(av, @S@);",
+ " return target.invokeExact(@av,@@sv@); }",
+ " //@end-S@",
+ " }",
+ } };
+ static final String NEWLINE_INDENT = "\n ";
+ enum VAR {
+ cat, N, S, av, av_, Tvav_, sv;
+ public final String pattern = "@"+toString().replace('_','.')+"@";
+ public String binding = toString();
+ static void makeBindings(boolean topLevel, int outargs, int spread) {
+ int inargs = outargs - spread;
+ VAR.cat.binding = "S"+outargs;
+ VAR.N.binding = String.valueOf(outargs); // outgoing arg count
+ VAR.S.binding = String.valueOf(spread); // spread count
+ String[] av = new String[inargs];
+ String[] Tvav = new String[inargs];
+ for (int i = 0; i < inargs; i++) {
+ av[i] = arg(i);
+ Tvav[i] = param("Object", av[i]);
+ }
+ VAR.av.binding = comma(av);
+ VAR.av_.binding = comma(av, ", ");
+ VAR.Tvav_.binding = comma(Tvav, ", ");
+ String[] sv = new String[spread];
+ for (int i = 0; i < spread; i++) {
+ String spc = "";
+ if (i % 4 == 0) spc = NEWLINE_INDENT;
+ sv[i] = spc+"super.select(av,"+i+")";
+ }
+ VAR.sv.binding = comma(sv);
+ }
+ static String arg(int i) { return "a"+i; }
+ static String param(String t, String a) { return t+" "+a; }
+ static String comma(String[] v) { return comma(v, ""); }
+ static String comma(String[] v, String sep) {
+ if (v.length == 0) return "";
+ String res = v[0];
+ for (int i = 1; i < v.length; i++) res += ", "+v[i];
+ return res + sep;
+ }
+ static String transform(String string) {
+ for (VAR var : values())
+ string = string.replaceAll(var.pattern, var.binding);
+ return string;
+ }
+ }
+ static String[] stringsIn(String[] strings, int beg, int end) {
+ return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
+ }
+ static String[] stringsBefore(String[] strings, int pos) {
+ return stringsIn(strings, 0, pos);
+ }
+ static String[] stringsAfter(String[] strings, int pos) {
+ return stringsIn(strings, pos, strings.length);
+ }
+ static int indexAfter(String[] strings, int pos, String tag) {
+ return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
+ }
+ static int indexBefore(String[] strings, int pos, String tag) {
+ for (int i = pos, end = strings.length; ; i++) {
+ if (i == end || strings[i].endsWith(tag)) return i;
+ }
+ }
+ static int MIN_ARITY, MAX_ARITY;
+ public static void main(String... av) {
+ for (String[] template : TEMPLATES) {
+ int forLinesLimit = indexBefore(template, 0, "@each-cat@");
+ String[] forLines = stringsBefore(template, forLinesLimit);
+ template = stringsAfter(template, forLinesLimit);
+ for (String forLine : forLines)
+ expandTemplate(forLine, template);
+ }
+ }
+ static void expandTemplate(String forLine, String[] template) {
+ String[] params = forLine.split("[^0-9]+");
+ if (params[0].length() == 0) params = stringsAfter(params, 1);
+ System.out.println("//params="+Arrays.asList(params));
+ int pcur = 0;
+ MIN_ARITY = Integer.valueOf(params[pcur++]);
+ MAX_ARITY = Integer.valueOf(params[pcur++]);
+ if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
+ for (int outargs = MIN_ARITY; outargs <= MAX_ARITY; outargs++) {
+ expandTemplate(template, true, outargs, 0);
+ }
+ }
+ static void expandTemplate(String[] template, boolean topLevel, int outargs, int spread) {
+ VAR.makeBindings(topLevel, outargs, spread);
+ for (int i = 0; i < template.length; i++) {
+ String line = template[i];
+ if (line.endsWith("@each-cat@")) {
+ // ignore
+ } else if (line.endsWith("@each-S@")) {
+ int blockEnd = indexAfter(template, i, "@end-S@");
+ String[] block = stringsIn(template, i+1, blockEnd-1);
+ for (int spread1 = spread+1; spread1 <= outargs; spread1++)
+ expandTemplate(block, false, outargs, spread1);
+ VAR.makeBindings(topLevel, outargs, spread);
+ i = blockEnd-1; continue;
+ } else {
+ System.out.println(VAR.transform(line));
+ }
+ }
+ }
+}
+//}}} */
+//params=[0, 10]
+ static class S0 extends Adapter {
+ protected S0(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S0(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S0 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S0(outer, t); }
+ protected Object invoke_S0(Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(); }
+ }
+ static class S1 extends Adapter {
+ protected S1(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S1(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S1 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S1(outer, t); }
+ protected Object invoke_S0(Object a0, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0); }
+ protected Object invoke_S1(Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(
+ super.select(av,0)); }
+ }
+ static class S2 extends Adapter {
+ protected S2(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S2(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1); }
+ protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1)); }
+ }
+ static class S3 extends Adapter {
+ protected S3(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S3(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S3 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S3(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1, a2); }
+ protected Object invoke_S1(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0, a1,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(a0,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object av) throws Throwable { av = super.check(av, 3);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ }
+ static class S4 extends Adapter {
+ protected S4(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S4(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S4 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S4(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1, a2, a3); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0, a1, a2,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(a0, a1,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object av) throws Throwable { av = super.check(av, 3);
+ return target.invokeExact(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object av) throws Throwable { av = super.check(av, 4);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ }
+ static class S5 extends Adapter {
+ protected S5(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S5(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S5 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S5(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1, a2, a3, a4); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0, a1, a2, a3,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(a0, a1, a2,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 3);
+ return target.invokeExact(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object av) throws Throwable { av = super.check(av, 4);
+ return target.invokeExact(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object av) throws Throwable { av = super.check(av, 5);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ }
+ static class S6 extends Adapter {
+ protected S6(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S6(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S6 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S6(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0, a1, a2, a3, a4,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 3);
+ return target.invokeExact(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 4);
+ return target.invokeExact(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object av) throws Throwable { av = super.check(av, 5);
+ return target.invokeExact(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object av) throws Throwable { av = super.check(av, 6);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ }
+ static class S7 extends Adapter {
+ protected S7(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S7(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S7 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S7(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(a0, a1, a2, a3, a4,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 3);
+ return target.invokeExact(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 4);
+ return target.invokeExact(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 5);
+ return target.invokeExact(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object a0, Object av) throws Throwable { av = super.check(av, 6);
+ return target.invokeExact(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ protected Object invoke_S7(Object av) throws Throwable { av = super.check(av, 7);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6)); }
+ }
+ static class S8 extends Adapter {
+ protected S8(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S8(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S8 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S8(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 3);
+ return target.invokeExact(a0, a1, a2, a3, a4,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 4);
+ return target.invokeExact(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 5);
+ return target.invokeExact(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 6);
+ return target.invokeExact(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ protected Object invoke_S7(Object a0, Object av) throws Throwable { av = super.check(av, 7);
+ return target.invokeExact(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6)); }
+ protected Object invoke_S8(Object av) throws Throwable { av = super.check(av, 8);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
+ }
+ static class S9 extends Adapter {
+ protected S9(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S9(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S9 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S9(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 3);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 4);
+ return target.invokeExact(a0, a1, a2, a3, a4,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 5);
+ return target.invokeExact(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 6);
+ return target.invokeExact(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ protected Object invoke_S7(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 7);
+ return target.invokeExact(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6)); }
+ protected Object invoke_S8(Object a0, Object av) throws Throwable { av = super.check(av, 8);
+ return target.invokeExact(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
+ protected Object invoke_S9(Object av) throws Throwable { av = super.check(av, 9);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
+ super.select(av,8)); }
+ }
+ static class S10 extends Adapter {
+ protected S10(SpreadGeneric outer) { super(outer); } // to build prototype
+ protected S10(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
+ protected S10 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S10(outer, t); }
+ protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9, Object av) throws Throwable { av = super.check(av, 0);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object av) throws Throwable { av = super.check(av, 1);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8,
+ super.select(av,0)); }
+ protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 2);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7,
+ super.select(av,0), super.select(av,1)); }
+ protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 3);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
+ super.select(av,0), super.select(av,1), super.select(av,2)); }
+ protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 4);
+ return target.invokeExact(a0, a1, a2, a3, a4, a5,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
+ protected Object invoke_S5(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 5);
+ return target.invokeExact(a0, a1, a2, a3, a4,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4)); }
+ protected Object invoke_S6(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 6);
+ return target.invokeExact(a0, a1, a2, a3,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5)); }
+ protected Object invoke_S7(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 7);
+ return target.invokeExact(a0, a1, a2,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6)); }
+ protected Object invoke_S8(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 8);
+ return target.invokeExact(a0, a1,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
+ protected Object invoke_S9(Object a0, Object av) throws Throwable { av = super.check(av, 9);
+ return target.invokeExact(a0,
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
+ super.select(av,8)); }
+ protected Object invoke_S10(Object av) throws Throwable { av = super.check(av, 10);
+ return target.invokeExact(
+ super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
+ super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
+ super.select(av,8), super.select(av,9)); }
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/SwitchPoint.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/SwitchPoint.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2010, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+/**
+ *
+ * A {@code SwitchPoint} is an object which can publish state transitions to other threads.
+ * A switch point is initially in the valid state, but may at any time be
+ * changed to the invalid state. Invalidation cannot be reversed.
+ * A switch point can combine a guarded pair of method handles into a
+ * guarded delegator .
+ * The guarded delegator is a method handle which delegates to one of the old method handles.
+ * The state of the switch point determines which of the two gets the delegation.
+ *
+ * A single switch point may be used to control any number of method handles.
+ * (Indirectly, therefore, it can control any number of call sites.)
+ * This is done by using the single switch point as a factory for combining
+ * any number of guarded method handle pairs into guarded delegators.
+ *
+ * When a guarded delegator is created from a guarded pair, the pair
+ * is wrapped in a new method handle {@code M},
+ * which is permanently associated with the switch point that created it.
+ * Each pair consists of a target {@code T} and a fallback {@code F}.
+ * While the switch point is valid, invocations to {@code M} are delegated to {@code T}.
+ * After it is invalidated, invocations are delegated to {@code F}.
+ *
+ * Invalidation is global and immediate, as if the switch point contained a
+ * volatile boolean variable consulted on every call to {@code M}.
+ * The invalidation is also permanent, which means the switch point
+ * can change state only once.
+ * The switch point will always delegate to {@code F} after being invalidated.
+ * At that point {@code guardWithTest} may ignore {@code T} and return {@code F}.
+ *
+ * Here is an example of a switch point in action:
+ *
+MethodType MT_str2 = MethodType.methodType(String.class, String.class);
+MethodHandle MH_strcat = MethodHandles.lookup()
+ .findVirtual(String.class, "concat", MT_str2);
+SwitchPoint spt = new SwitchPoint();
+// the following steps may be repeated to re-use the same switch point:
+MethodHandle worker1 = strcat;
+MethodHandle worker2 = MethodHandles.permuteArguments(strcat, MT_str2, 1, 0);
+MethodHandle worker = spt.guardWithTest(worker1, worker2);
+assertEquals("method", (String) worker.invokeExact("met", "hod"));
+SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });
+assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
+ *
+ *
+ * Discussion:
+ * Switch points are useful without subclassing. They may also be subclassed.
+ * This may be useful in order to associate application-specific invalidation logic
+ * with the switch point.
+ * Notice that there is no permanent association between a switch point and
+ * the method handles it produces and consumes.
+ * The garbage collector may collect method handles produced or consumed
+ * by a switch point independently of the lifetime of the switch point itself.
+ *
+ * Implementation Note:
+ * A switch point behaves as if implemented on top of {@link MutableCallSite},
+ * approximately as follows:
+ *
+public class SwitchPoint {
+ private static final MethodHandle
+ K_true = MethodHandles.constant(boolean.class, true),
+ K_false = MethodHandles.constant(boolean.class, false);
+ private final MutableCallSite mcs;
+ private final MethodHandle mcsInvoker;
+ public SwitchPoint() {
+ this.mcs = new MutableCallSite(K_true);
+ this.mcsInvoker = mcs.dynamicInvoker();
+ }
+ public MethodHandle guardWithTest(
+ MethodHandle target, MethodHandle fallback) {
+ // Note: mcsInvoker is of type ()boolean.
+ // Target and fallback may take any arguments, but must have the same type.
+ return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback);
+ }
+ public static void invalidateAll(SwitchPoint[] spts) {
+ List<MutableCallSite> mcss = new ArrayList<>();
+ for (SwitchPoint spt : spts) mcss.add(spt.mcs);
+ for (MutableCallSite mcs : mcss) mcs.setTarget(K_false);
+ MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0]));
+ }
+}
+ *
+ * @author Remi Forax, JSR 292 EG
+ */
+public class SwitchPoint {
+ private static final MethodHandle
+ K_true = MethodHandles.constant(boolean.class, true),
+ K_false = MethodHandles.constant(boolean.class, false);
+
+ private final MutableCallSite mcs;
+ private final MethodHandle mcsInvoker;
+
+ /**
+ * Creates a new switch point.
+ */
+ public SwitchPoint() {
+ this.mcs = new MutableCallSite(K_true);
+ this.mcsInvoker = mcs.dynamicInvoker();
+ }
+
+ /**
+ * Returns a method handle which always delegates either to the target or the fallback.
+ * The method handle will delegate to the target exactly as long as the switch point is valid.
+ * After that, it will permanently delegate to the fallback.
+ *
+ * The target and fallback must be of exactly the same method type,
+ * and the resulting combined method handle will also be of this type.
+ *
+ * @param target the method handle selected by the switch point as long as it is valid
+ * @param fallback the method handle selected by the switch point after it is invalidated
+ * @return a combined method handle which always calls either the target or fallback
+ * @throws NullPointerException if either argument is null
+ * @see MethodHandles#guardWithTest
+ */
+ public MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback) {
+ if (mcs.getTarget() == K_false)
+ return fallback; // already invalid
+ return MethodHandles.guardWithTest(mcsInvoker, target, fallback);
+ }
+
+ /**
+ * Sets all of the given switch points into the invalid state.
+ * After this call executes, no thread will observe any of the
+ * switch points to be in a valid state.
+ *
+ * This operation is likely to be expensive and should be used sparingly.
+ * If possible, it should be buffered for batch processing on sets of switch points.
+ *
+ * If {@code switchPoints} contains a null element,
+ * a {@code NullPointerException} will be raised.
+ * In this case, some non-null elements in the array may be
+ * processed before the method returns abnormally.
+ * Which elements these are (if any) is implementation-dependent.
+ *
+ *
+ * Discussion:
+ * For performance reasons, {@code invalidateAll} is not a virtual method
+ * on a single switch point, but rather applies to a set of switch points.
+ * Some implementations may incur a large fixed overhead cost
+ * for processing one or more invalidation operations,
+ * but a small incremental cost for each additional invalidation.
+ * In any case, this operation is likely to be costly, since
+ * other threads may have to be somehow interrupted
+ * in order to make them notice the updated switch point state.
+ * However, it may be observed that a single call to invalidate
+ * several switch points has the same formal effect as many calls,
+ * each on just one of the switch points.
+ *
+ *
+ * Implementation Note:
+ * Simple implementations of {@code SwitchPoint} may use
+ * a private {@link MutableCallSite} to publish the state of a switch point.
+ * In such an implementation, the {@code invalidateAll} method can
+ * simply change the call site's target, and issue one call to
+ * {@linkplain MutableCallSite#syncAll synchronize} all the
+ * private call sites.
+ *
+ * @param switchPoints an array of call sites to be synchronized
+ * @throws NullPointerException if the {@code switchPoints} array reference is null
+ * or the array contains a null
+ */
+ public static void invalidateAll(SwitchPoint[] switchPoints) {
+ if (switchPoints.length == 0) return;
+ MutableCallSite[] sites = new MutableCallSite[switchPoints.length];
+ for (int i = 0; i < switchPoints.length; i++) {
+ SwitchPoint spt = switchPoints[i];
+ if (spt == null) break; // MSC.syncAll will trigger a NPE
+ sites[i] = spt.mcs;
+ spt.mcs.setTarget(K_false);
+ }
+ MutableCallSite.syncAll(sites);
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/ToGeneric.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/ToGeneric.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,1062 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.Wrapper;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * Adapters which mediate between incoming calls which are not generic
+ * and outgoing calls which are. Any call can be represented generically
+ * boxing up its arguments, and (on return) unboxing the return value.
+ *
+ * A call is "generic" (in MethodHandle terms) if its MethodType features
+ * only Object arguments. A non-generic call therefore features
+ * primitives and/or reference types other than Object.
+ * An adapter has types for its incoming and outgoing calls.
+ * The incoming call type is simply determined by the adapter's type
+ * (the MethodType it presents to callers). The outgoing call type
+ * is determined by the adapter's target (a MethodHandle that the adapter
+ * either binds internally or else takes as a leading argument).
+ * (To stretch the term, adapter-like method handles may have multiple
+ * targets or be polymorphic across multiple call types.)
+ * @author jrose
+ */
+class ToGeneric {
+ // type for the incoming call (may be erased)
+ private final MethodType entryType;
+ // incoming type with primitives moved to the end and turned to int/long
+ private final MethodType rawEntryType;
+ // adapter for the erased type
+ private final Adapter adapter;
+ // entry point for adapter (Adapter mh, a...) => ...
+ private final MethodHandle entryPoint;
+ // permutation of arguments for primsAtEndType
+ private final int[] primsAtEndOrder;
+ // optional final argument list conversions (at least, invokes the target)
+ private final MethodHandle invoker;
+ // conversion which unboxes a primitive return value
+ private final MethodHandle returnConversion;
+
+ /** Compute and cache information common to all generifying (boxing) adapters
+ * that implement members of the erasure-family of the given erased type.
+ */
+ private ToGeneric(MethodType entryType) {
+ assert(entryType.erase() == entryType); // for now
+ // incoming call will first "forget" all reference types except Object
+ this.entryType = entryType;
+ MethodHandle invoker0 = entryType.generic().invokers().exactInvoker();
+ MethodType rawEntryTypeInit;
+ Adapter ad = findAdapter(rawEntryTypeInit = entryType);
+ if (ad != null) {
+ // Immediate hit to exactly the adapter we want,
+ // with no monkeying around with primitive types.
+ this.returnConversion = computeReturnConversion(entryType, rawEntryTypeInit, false);
+ this.rawEntryType = rawEntryTypeInit;
+ this.adapter = ad;
+ this.entryPoint = ad.prototypeEntryPoint();
+ this.primsAtEndOrder = null;
+ this.invoker = invoker0;
+ return;
+ }
+
+ // next, it will reorder primitives after references
+ MethodType primsAtEnd = entryType.form().primsAtEnd();
+ // at the same time, it will "forget" all primitive types except int/long
+ this.primsAtEndOrder = MethodTypeForm.primsAtEndOrder(entryType);
+ if (primsAtEndOrder != null) {
+ // reordering is required; build on top of a simpler ToGeneric
+ ToGeneric va2 = ToGeneric.of(primsAtEnd);
+ this.adapter = va2.adapter;
+ if (true) throw new UnsupportedOperationException("NYI: primitive parameters must follow references; entryType = "+entryType);
+ this.entryPoint = MethodHandleImpl.convertArguments(
+ va2.entryPoint, primsAtEnd, entryType, primsAtEndOrder);
+ // example: for entryType of (int,Object,Object), the reordered
+ // type is (Object,Object,int) and the order is {1,2,0},
+ // and putPAE is (mh,int0,obj1,obj2) => mh.invokeExact(obj1,obj2,int0)
+ return;
+ }
+
+ // after any needed argument reordering, it will reinterpret
+ // primitive arguments according to their "raw" types int/long
+ MethodType intsAtEnd = primsAtEnd.form().primsAsInts();
+ ad = findAdapter(rawEntryTypeInit = intsAtEnd);
+ MethodHandle rawEntryPoint;
+ if (ad != null) {
+ rawEntryPoint = ad.prototypeEntryPoint();
+ } else {
+ // Perhaps the adapter is available only for longs.
+ // If so, we can use it, but there will have to be a little
+ // more stack motion on each call.
+ MethodType longsAtEnd = primsAtEnd.form().primsAsLongs();
+ ad = findAdapter(rawEntryTypeInit = longsAtEnd);
+ if (ad != null) {
+ MethodType eptWithLongs = longsAtEnd.insertParameterTypes(0, ad.getClass());
+ MethodType eptWithInts = intsAtEnd.insertParameterTypes(0, ad.getClass());
+ rawEntryPoint = ad.prototypeEntryPoint();
+ MethodType midType = eptWithLongs; // will change longs to ints
+ for (int i = 0, nargs = midType.parameterCount(); i < nargs; i++) {
+ if (midType.parameterType(i) != eptWithInts.parameterType(i)) {
+ assert(midType.parameterType(i) == long.class);
+ assert(eptWithInts.parameterType(i) == int.class);
+ MethodType nextType = midType.changeParameterType(i, int.class);
+ rawEntryPoint = MethodHandleImpl.convertArguments(
+ rawEntryPoint, nextType, midType, null);
+ midType = nextType;
+ }
+ }
+ assert(midType == eptWithInts);
+ } else {
+ // If there is no statically compiled adapter,
+ // build one by means of dynamic bytecode generation.
+ ad = buildAdapterFromBytecodes(rawEntryTypeInit = intsAtEnd);
+ rawEntryPoint = ad.prototypeEntryPoint();
+ }
+ }
+ MethodType tepType = entryType.insertParameterTypes(0, ad.getClass());
+ this.entryPoint =
+ AdapterMethodHandle.makeRetypeRaw(tepType, rawEntryPoint);
+ if (this.entryPoint == null)
+ throw new UnsupportedOperationException("cannot retype to "+entryType
+ +" from "+rawEntryPoint.type().dropParameterTypes(0, 1));
+ this.returnConversion = computeReturnConversion(entryType, rawEntryTypeInit, false);
+ this.rawEntryType = rawEntryTypeInit;
+ this.adapter = ad;
+ this.invoker = makeRawArgumentFilter(invoker0, rawEntryTypeInit, entryType);
+ }
+
+ /** A generic argument list will be created by a call of type 'raw'.
+ * The values need to be reboxed for to match 'cooked'.
+ * Do this on the fly.
+ */
+ // TO DO: Use a generic argument converter in a different file
+ static MethodHandle makeRawArgumentFilter(MethodHandle invoker,
+ MethodType raw, MethodType cooked) {
+ MethodHandle filteredInvoker = null;
+ for (int i = 0, nargs = raw.parameterCount(); i < nargs; i++) {
+ Class> src = raw.parameterType(i);
+ Class> dst = cooked.parameterType(i);
+ if (src == dst) continue;
+ assert(src.isPrimitive() && dst.isPrimitive());
+ if (filteredInvoker == null) {
+ filteredInvoker =
+ AdapterMethodHandle.makeCheckCast(
+ invoker.type().generic(), invoker, 0, MethodHandle.class);
+ if (filteredInvoker == null) throw new UnsupportedOperationException("NYI");
+ }
+ MethodHandle reboxer = ValueConversions.rebox(dst, false);
+ filteredInvoker = FilterGeneric.makeArgumentFilter(1+i, reboxer, filteredInvoker);
+ if (filteredInvoker == null) throw new InternalError();
+ }
+ if (filteredInvoker == null) return invoker;
+ return AdapterMethodHandle.makeRetypeOnly(invoker.type(), filteredInvoker);
+ }
+
+ /**
+ * Caller will be expecting a result from a call to {@code type},
+ * while the internal adapter entry point is rawEntryType.
+ * Also, the internal target method will be returning a boxed value,
+ * as an untyped object.
+ *
+ * Produce a value converter which will be typed to convert from
+ * {@code Object} to the return value of {@code rawEntryType}, and will
+ * in fact ensure that the value is compatible with the return type of
+ * {@code type}.
+ */
+ private static MethodHandle computeReturnConversion(
+ MethodType type, MethodType rawEntryType, boolean mustCast) {
+ Class> tret = type.returnType();
+ Class> rret = rawEntryType.returnType();
+ if (mustCast || !tret.isPrimitive()) {
+ assert(!tret.isPrimitive());
+ assert(!rret.isPrimitive());
+ if (rret == Object.class && !mustCast)
+ return null;
+ return ValueConversions.cast(tret, false);
+ } else if (tret == rret) {
+ return ValueConversions.unbox(tret, false);
+ } else {
+ assert(rret.isPrimitive());
+ assert(tret == double.class ? rret == long.class : rret == int.class);
+ return ValueConversions.unboxRaw(tret, false);
+ }
+ }
+
+ Adapter makeInstance(MethodType type, MethodHandle genericTarget) {
+ genericTarget.getClass(); // check for NPE
+ MethodHandle convert = returnConversion;
+ if (primsAtEndOrder != null)
+ // reorder arguments passed to genericTarget, if primsAtEndOrder
+ throw new UnsupportedOperationException("NYI");
+ if (type == entryType) {
+ if (convert == null) convert = ValueConversions.identity();
+ return adapter.makeInstance(entryPoint, invoker, convert, genericTarget);
+ }
+ // my erased-type is not exactly the same as the desired type
+ assert(type.erase() == entryType); // else we are busted
+ if (convert == null)
+ convert = computeReturnConversion(type, rawEntryType, true);
+ // retype erased reference arguments (the cast makes it safe to do this)
+ MethodType tepType = type.insertParameterTypes(0, adapter.getClass());
+ MethodHandle typedEntryPoint =
+ AdapterMethodHandle.makeRetypeRaw(tepType, entryPoint);
+ return adapter.makeInstance(typedEntryPoint, invoker, convert, genericTarget);
+ }
+
+ /** Build an adapter of the given type, which invokes genericTarget
+ * on the incoming arguments, after boxing as necessary.
+ * The return value is unboxed if necessary.
+ * @param type the required type of the
+ * @param genericTarget the target, which must accept and return only Object values
+ * @return an adapter method handle
+ */
+ public static MethodHandle make(MethodType type, MethodHandle genericTarget) {
+ MethodType gtype = genericTarget.type();
+ if (type.generic() != gtype)
+ throw newIllegalArgumentException("type must be generic");
+ if (type == gtype) return genericTarget;
+ return ToGeneric.of(type).makeInstance(type, genericTarget);
+ }
+
+ /** Return the adapter information for this type's erasure. */
+ static ToGeneric of(MethodType type) {
+ MethodTypeForm form = type.form();
+ ToGeneric toGen = form.toGeneric;
+ if (toGen == null)
+ form.toGeneric = toGen = new ToGeneric(form.erasedType());
+ return toGen;
+ }
+
+ public String toString() {
+ return "ToGeneric"+entryType
+ +(primsAtEndOrder!=null?"[reorder]":"");
+ }
+
+ /* Create an adapter for the given incoming call type. */
+ static Adapter findAdapter(MethodType entryPointType) {
+ MethodTypeForm form = entryPointType.form();
+ Class> rtype = entryPointType.returnType();
+ int argc = form.parameterCount();
+ int lac = form.longPrimitiveParameterCount();
+ int iac = form.primitiveParameterCount() - lac;
+ String intsAndLongs = (iac > 0 ? "I"+iac : "")+(lac > 0 ? "J"+lac : "");
+ String rawReturn = String.valueOf(Wrapper.forPrimitiveType(rtype).basicTypeChar());
+ String iname0 = "invoke_"+rawReturn;
+ String iname1 = "invoke";
+ String[] inames = { iname0, iname1 };
+ String cname0 = rawReturn + argc;
+ String cname1 = "A" + argc;
+ String[] cnames = { cname1, cname1+intsAndLongs, cname0, cname0+intsAndLongs };
+ // e.g., D5I2, D5, L5I2, L5
+ for (String cname : cnames) {
+ Class extends Adapter> acls = Adapter.findSubClass(cname);
+ if (acls == null) continue;
+ // see if it has the required invoke method
+ for (String iname : inames) {
+ MethodHandle entryPoint = null;
+ try {
+ entryPoint = IMPL_LOOKUP.
+ findSpecial(acls, iname, entryPointType, acls);
+ } catch (ReflectiveOperationException ex) {
+ }
+ if (entryPoint == null) continue;
+ Constructor extends Adapter> ctor = null;
+ try {
+ // Prototype builder:
+ ctor = acls.getDeclaredConstructor(MethodHandle.class);
+ } catch (NoSuchMethodException ex) {
+ } catch (SecurityException ex) {
+ }
+ if (ctor == null) continue;
+ try {
+ return ctor.newInstance(entryPoint);
+ } catch (IllegalArgumentException ex) {
+ } catch (InvocationTargetException wex) {
+ Throwable ex = wex.getTargetException();
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ } catch (InstantiationException ex) {
+ } catch (IllegalAccessException ex) {
+ }
+ }
+ }
+ return null;
+ }
+
+ static Adapter buildAdapterFromBytecodes(MethodType entryPointType) {
+ throw new UnsupportedOperationException("NYI");
+ }
+
+ /**
+ * The invoke method takes some particular but unconstrained spread
+ * of raw argument types, and returns a raw return type (in L/I/J/F/D).
+ * Internally, it converts the incoming arguments uniformly into objects.
+ * This series of objects is then passed to the {@code target} method,
+ * which returns a result object. This result is finally converted,
+ * via another method handle {@code convert}, which is responsible for
+ * converting the object result into the raw return value.
+ */
+ static abstract class Adapter extends BoundMethodHandle {
+ /*
+ * class X<> extends Adapter {
+ * Object...=>Object target;
+ * Object=>R convert;
+ * R invoke(A... a...) = convert(invoker(target, a...)))
+ * }
+ */
+ protected final MethodHandle invoker; // (MH, Object...) -> Object
+ protected final MethodHandle target; // Object... -> Object
+ protected final MethodHandle convert; // Object -> R
+
+ @Override
+ public String toString() {
+ return target == null ? "prototype:"+convert : addTypeString(target, this);
+ }
+
+ protected boolean isPrototype() { return target == null; }
+ /* Prototype constructor. */
+ protected Adapter(MethodHandle entryPoint) {
+ super(entryPoint);
+ this.invoker = null;
+ this.convert = entryPoint;
+ this.target = null;
+ assert(isPrototype());
+ }
+ protected MethodHandle prototypeEntryPoint() {
+ if (!isPrototype()) throw new InternalError();
+ return convert;
+ }
+
+ protected Adapter(MethodHandle entryPoint, MethodHandle invoker, MethodHandle convert, MethodHandle target) {
+ super(entryPoint);
+ this.invoker = invoker;
+ this.convert = convert;
+ this.target = target;
+ }
+
+ /** Make a copy of self, with new fields. */
+ protected abstract Adapter makeInstance(MethodHandle entryPoint,
+ MethodHandle invoker, MethodHandle convert, MethodHandle target);
+ // { return new ThisType(entryPoint, convert, target); }
+
+ // Code to run when the arguments (<= 4) have all been boxed.
+ protected Object target() throws Throwable { return invoker.invokeExact(target); }
+ protected Object target(Object a0) throws Throwable { return invoker.invokeExact(target, a0); }
+ protected Object target(Object a0, Object a1)
+ throws Throwable { return invoker.invokeExact(target, a0, a1); }
+ protected Object target(Object a0, Object a1, Object a2)
+ throws Throwable { return invoker.invokeExact(target, a0, a1, a2); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3)
+ throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3); }
+ /*
+ protected Object target_0(Object... av) throws Throwable { return invoker.invokeExact(target, av); }
+ protected Object target_1(Object a0, Object... av)
+ throws Throwable { return invoker.invokeExact(target, a0, (Object)av); }
+ protected Object target_2(Object a0, Object a1, Object... av)
+ throws Throwable { return invoker.invokeExact(target, a0, a1, (Object)av); }
+ protected Object target_3(Object a0, Object a1, Object a2, Object... av)
+ throws Throwable { return invoker.invokeExact(target, a0, a1, a2, (Object)av); }
+ protected Object target_4(Object a0, Object a1, Object a2, Object a3, Object... av)
+ throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, (Object)av); }
+ // */
+ // (For more than 4 arguments, generate the code in the adapter itself.)
+
+ // Code to run when the generic target has finished and produced a value.
+ protected Object return_L(Object res) throws Throwable { return (Object)convert.invokeExact(res); }
+ protected int return_I(Object res) throws Throwable { return (int) convert.invokeExact(res); }
+ protected long return_J(Object res) throws Throwable { return (long) convert.invokeExact(res); }
+ protected float return_F(Object res) throws Throwable { return (float) convert.invokeExact(res); }
+ protected double return_D(Object res) throws Throwable { return (double)convert.invokeExact(res); }
+
+ static private final String CLASS_PREFIX; // "java.lang.invoke.ToGeneric$"
+ static {
+ String aname = Adapter.class.getName();
+ String sname = Adapter.class.getSimpleName();
+ if (!aname.endsWith(sname)) throw new InternalError();
+ CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
+ }
+ /** Find a sibing class of Adapter. */
+ static Class extends Adapter> findSubClass(String name) {
+ String cname = Adapter.CLASS_PREFIX + name;
+ try {
+ return Class.forName(cname).asSubclass(Adapter.class);
+ } catch (ClassNotFoundException ex) {
+ return null;
+ } catch (ClassCastException ex) {
+ return null;
+ }
+ }
+ }
+
+ /* generated classes follow this pattern:
+ static class A1 extends Adapter {
+ protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
+ protected Object target(Object a0) throws Throwable { return invoker.invokeExact(target, a0); }
+ protected Object targetA1(Object a0) throws Throwable { return target(a0); }
+ protected Object targetA1(int a0) throws Throwable { return target(a0); }
+ protected Object targetA1(long a0) throws Throwable { return target(a0); }
+ protected Object invoke_L(Object a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(Object a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(Object a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(Object a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(Object a0) throws Throwable { return return_D(targetA1(a0)); }
+ protected Object invoke_L(int a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(int a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(int a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(int a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(int a0) throws Throwable { return return_D(targetA1(a0)); }
+ protected Object invoke_L(long a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(long a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(long a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(long a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(long a0) throws Throwable { return return_D(targetA1(a0)); }
+ }
+ // */
+
+/*
+: SHELL; n=ToGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
+//{{{
+import java.util.*;
+class genclasses {
+ static String[] TYPES = { "Object", "int ", "long ", "float ", "double" };
+ static String[] TCHARS = { "L", "I", "J", "F", "D", "A" };
+ static String[][] TEMPLATES = { {
+ "@for@ arity=0..3 rcat<=4 nrefs<=99 nints<=99 nlongs<=99",
+ "@for@ arity=4..4 rcat<=4 nrefs<=99 nints<=99 nlongs<=99",
+ "@for@ arity=5..5 rcat<=2 nrefs<=99 nints<=99 nlongs<=99",
+ "@for@ arity=6..10 rcat<=2 nrefs<=99 nints=0 nlongs<=99",
+ " //@each-cat@",
+ " static class @cat@ extends Adapter {",
+ " protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
+ " protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }",
+ " protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }",
+ " protected Object target(@Ovav@) throws Throwable { return invoker.invokeExact(target@comma@@av@); }",
+ " //@each-Tv@",
+ " protected Object target@cat@(@Tvav@) throws Throwable { return target(@av@); }",
+ " //@end-Tv@",
+ " //@each-Tv@",
+ " //@each-R@",
+ " protected @R@ invoke_@Rc@(@Tvav@) throws Throwable { return return_@Rc@(target@cat@(@av@)); }",
+ " //@end-R@",
+ " //@end-Tv@",
+ " }",
+ } };
+ enum VAR {
+ cat, R, Rc, Tv, av, comma, Tvav, Ovav;
+ public final String pattern = "@"+toString().replace('_','.')+"@";
+ public String binding;
+ static void makeBindings(boolean topLevel, int rcat, int nrefs, int nints, int nlongs) {
+ int nargs = nrefs + nints + nlongs;
+ if (topLevel)
+ VAR.cat.binding = catstr(ALL_RETURN_TYPES ? TYPES.length : rcat, nrefs, nints, nlongs);
+ VAR.R.binding = TYPES[rcat];
+ VAR.Rc.binding = TCHARS[rcat];
+ String[] Tv = new String[nargs];
+ String[] av = new String[nargs];
+ String[] Tvav = new String[nargs];
+ String[] Ovav = new String[nargs];
+ for (int i = 0; i < nargs; i++) {
+ int tcat = (i < nrefs) ? 0 : (i < nrefs + nints) ? 1 : 2;
+ Tv[i] = TYPES[tcat];
+ av[i] = arg(i);
+ Tvav[i] = param(Tv[i], av[i]);
+ Ovav[i] = param("Object", av[i]);
+ }
+ VAR.Tv.binding = comma(Tv);
+ VAR.av.binding = comma(av);
+ VAR.comma.binding = (av.length == 0 ? "" : ", ");
+ VAR.Tvav.binding = comma(Tvav);
+ VAR.Ovav.binding = comma(Ovav);
+ }
+ static String arg(int i) { return "a"+i; }
+ static String param(String t, String a) { return t+" "+a; }
+ static String comma(String[] v) { return comma("", v); }
+ static String comma(String sep, String[] v) {
+ if (v.length == 0) return "";
+ String res = sep+v[0];
+ for (int i = 1; i < v.length; i++) res += ", "+v[i];
+ return res;
+ }
+ static String transform(String string) {
+ for (VAR var : values())
+ string = string.replaceAll(var.pattern, var.binding);
+ return string;
+ }
+ }
+ static String[] stringsIn(String[] strings, int beg, int end) {
+ return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
+ }
+ static String[] stringsBefore(String[] strings, int pos) {
+ return stringsIn(strings, 0, pos);
+ }
+ static String[] stringsAfter(String[] strings, int pos) {
+ return stringsIn(strings, pos, strings.length);
+ }
+ static int indexAfter(String[] strings, int pos, String tag) {
+ return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
+ }
+ static int indexBefore(String[] strings, int pos, String tag) {
+ for (int i = pos, end = strings.length; ; i++) {
+ if (i == end || strings[i].endsWith(tag)) return i;
+ }
+ }
+ static int MIN_ARITY, MAX_ARITY, MAX_RCAT, MAX_REFS, MAX_INTS, MAX_LONGS;
+ static boolean ALL_ARG_TYPES, ALL_RETURN_TYPES;
+ static HashSet done = new HashSet();
+ public static void main(String... av) {
+ for (String[] template : TEMPLATES) {
+ int forLinesLimit = indexBefore(template, 0, "@each-cat@");
+ String[] forLines = stringsBefore(template, forLinesLimit);
+ template = stringsAfter(template, forLinesLimit);
+ for (String forLine : forLines)
+ expandTemplate(forLine, template);
+ }
+ }
+ static void expandTemplate(String forLine, String[] template) {
+ String[] params = forLine.split("[^0-9]+");
+ if (params[0].length() == 0) params = stringsAfter(params, 1);
+ System.out.println("//params="+Arrays.asList(params));
+ int pcur = 0;
+ MIN_ARITY = Integer.valueOf(params[pcur++]);
+ MAX_ARITY = Integer.valueOf(params[pcur++]);
+ MAX_RCAT = Integer.valueOf(params[pcur++]);
+ MAX_REFS = Integer.valueOf(params[pcur++]);
+ MAX_INTS = Integer.valueOf(params[pcur++]);
+ MAX_LONGS = Integer.valueOf(params[pcur++]);
+ if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
+ if (MAX_RCAT >= TYPES.length) MAX_RCAT = TYPES.length - 1;
+ ALL_ARG_TYPES = (indexBefore(template, 0, "@each-Tv@") < template.length);
+ ALL_RETURN_TYPES = (indexBefore(template, 0, "@each-R@") < template.length);
+ for (int nargs = MIN_ARITY; nargs <= MAX_ARITY; nargs++) {
+ for (int rcat = 0; rcat <= MAX_RCAT; rcat++) {
+ expandTemplate(template, true, rcat, nargs, 0, 0);
+ if (ALL_ARG_TYPES) break;
+ expandTemplateForPrims(template, true, rcat, nargs, 1, 1);
+ if (ALL_RETURN_TYPES) break;
+ }
+ }
+ }
+ static String catstr(int rcat, int nrefs, int nints, int nlongs) {
+ int nargs = nrefs + nints + nlongs;
+ String cat = TCHARS[rcat] + nargs;
+ if (!ALL_ARG_TYPES) cat += (nints==0?"":"I"+nints)+(nlongs==0?"":"J"+nlongs);
+ return cat;
+ }
+ static void expandTemplateForPrims(String[] template, boolean topLevel, int rcat, int nargs, int minints, int minlongs) {
+ for (int isLong = 0; isLong <= 1; isLong++) {
+ for (int nprims = 1; nprims <= nargs; nprims++) {
+ int nrefs = nargs - nprims;
+ int nints = ((1-isLong) * nprims);
+ int nlongs = (isLong * nprims);
+ expandTemplate(template, topLevel, rcat, nrefs, nints, nlongs);
+ }
+ }
+ }
+ static void expandTemplate(String[] template, boolean topLevel,
+ int rcat, int nrefs, int nints, int nlongs) {
+ int nargs = nrefs + nints + nlongs;
+ if (nrefs > MAX_REFS || nints > MAX_INTS || nlongs > MAX_LONGS) return;
+ VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
+ if (topLevel && !done.add(VAR.cat.binding)) {
+ System.out.println(" //repeat "+VAR.cat.binding);
+ return;
+ }
+ for (int i = 0; i < template.length; i++) {
+ String line = template[i];
+ if (line.endsWith("@each-cat@")) {
+ // ignore
+ } else if (line.endsWith("@each-R@")) {
+ int blockEnd = indexAfter(template, i, "@end-R@");
+ String[] block = stringsIn(template, i+1, blockEnd-1);
+ for (int rcat1 = rcat; rcat1 <= MAX_RCAT; rcat1++)
+ expandTemplate(block, false, rcat1, nrefs, nints, nlongs);
+ VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
+ i = blockEnd-1; continue;
+ } else if (line.endsWith("@each-Tv@")) {
+ int blockEnd = indexAfter(template, i, "@end-Tv@");
+ String[] block = stringsIn(template, i+1, blockEnd-1);
+ expandTemplate(block, false, rcat, nrefs, nints, nlongs);
+ expandTemplateForPrims(block, false, rcat, nargs, nints+1, nlongs+1);
+ VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
+ i = blockEnd-1; continue;
+ } else {
+ System.out.println(VAR.transform(line));
+ }
+ }
+ }
+}
+//}}} */
+//params=[0, 3, 4, 99, 99, 99]
+ static class A0 extends Adapter {
+ protected A0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A0(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A0(e, i, c, t); }
+ protected Object target() throws Throwable { return invoker.invokeExact(target); }
+ protected Object targetA0() throws Throwable { return target(); }
+ protected Object invoke_L() throws Throwable { return return_L(targetA0()); }
+ protected int invoke_I() throws Throwable { return return_I(targetA0()); }
+ protected long invoke_J() throws Throwable { return return_J(targetA0()); }
+ protected float invoke_F() throws Throwable { return return_F(targetA0()); }
+ protected double invoke_D() throws Throwable { return return_D(targetA0()); }
+ }
+ static class A1 extends Adapter {
+ protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
+ protected Object target(Object a0) throws Throwable { return invoker.invokeExact(target, a0); }
+ protected Object targetA1(Object a0) throws Throwable { return target(a0); }
+ protected Object targetA1(int a0) throws Throwable { return target(a0); }
+ protected Object targetA1(long a0) throws Throwable { return target(a0); }
+ protected Object invoke_L(Object a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(Object a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(Object a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(Object a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(Object a0) throws Throwable { return return_D(targetA1(a0)); }
+ protected Object invoke_L(int a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(int a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(int a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(int a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(int a0) throws Throwable { return return_D(targetA1(a0)); }
+ protected Object invoke_L(long a0) throws Throwable { return return_L(targetA1(a0)); }
+ protected int invoke_I(long a0) throws Throwable { return return_I(targetA1(a0)); }
+ protected long invoke_J(long a0) throws Throwable { return return_J(targetA1(a0)); }
+ protected float invoke_F(long a0) throws Throwable { return return_F(targetA1(a0)); }
+ protected double invoke_D(long a0) throws Throwable { return return_D(targetA1(a0)); }
+ }
+ static class A2 extends Adapter {
+ protected A2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A2(e, i, c, t); }
+ protected Object target(Object a0, Object a1) throws Throwable { return invoker.invokeExact(target, a0, a1); }
+ protected Object targetA2(Object a0, Object a1) throws Throwable { return target(a0, a1); }
+ protected Object targetA2(Object a0, int a1) throws Throwable { return target(a0, a1); }
+ protected Object targetA2(int a0, int a1) throws Throwable { return target(a0, a1); }
+ protected Object targetA2(Object a0, long a1) throws Throwable { return target(a0, a1); }
+ protected Object targetA2(long a0, long a1) throws Throwable { return target(a0, a1); }
+ protected Object invoke_L(Object a0, Object a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(Object a0, Object a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(Object a0, Object a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(Object a0, Object a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(Object a0, Object a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ protected Object invoke_L(Object a0, int a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(Object a0, int a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(Object a0, int a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(Object a0, int a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(Object a0, int a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ protected Object invoke_L(int a0, int a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(int a0, int a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(int a0, int a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(int a0, int a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(int a0, int a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ protected Object invoke_L(Object a0, long a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(Object a0, long a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(Object a0, long a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(Object a0, long a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(Object a0, long a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ protected Object invoke_L(long a0, long a1) throws Throwable { return return_L(targetA2(a0, a1)); }
+ protected int invoke_I(long a0, long a1) throws Throwable { return return_I(targetA2(a0, a1)); }
+ protected long invoke_J(long a0, long a1) throws Throwable { return return_J(targetA2(a0, a1)); }
+ protected float invoke_F(long a0, long a1) throws Throwable { return return_F(targetA2(a0, a1)); }
+ protected double invoke_D(long a0, long a1) throws Throwable { return return_D(targetA2(a0, a1)); }
+ }
+ static class A3 extends Adapter {
+ protected A3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A3(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A3 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A3(e, i, c, t); }
+ protected Object target(Object a0, Object a1, Object a2) throws Throwable { return invoker.invokeExact(target, a0, a1, a2); }
+ protected Object targetA3(Object a0, Object a1, Object a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(Object a0, Object a1, int a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(Object a0, int a1, int a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(int a0, int a1, int a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(Object a0, Object a1, long a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(Object a0, long a1, long a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object targetA3(long a0, long a1, long a2) throws Throwable { return target(a0, a1, a2); }
+ protected Object invoke_L(Object a0, Object a1, Object a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, Object a1, Object a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, Object a1, Object a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, Object a1, Object a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, Object a1, Object a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(Object a0, Object a1, int a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, Object a1, int a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, Object a1, int a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, Object a1, int a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, Object a1, int a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(Object a0, int a1, int a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, int a1, int a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, int a1, int a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, int a1, int a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, int a1, int a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(int a0, int a1, int a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(int a0, int a1, int a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(int a0, int a1, int a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(int a0, int a1, int a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(int a0, int a1, int a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(Object a0, Object a1, long a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, Object a1, long a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, Object a1, long a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, Object a1, long a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, Object a1, long a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(Object a0, long a1, long a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(Object a0, long a1, long a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(Object a0, long a1, long a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(Object a0, long a1, long a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(Object a0, long a1, long a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ protected Object invoke_L(long a0, long a1, long a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
+ protected int invoke_I(long a0, long a1, long a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
+ protected long invoke_J(long a0, long a1, long a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
+ protected float invoke_F(long a0, long a1, long a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
+ protected double invoke_D(long a0, long a1, long a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
+ }
+//params=[4, 4, 4, 99, 99, 99]
+ static class A4 extends Adapter {
+ protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A4(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A4 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A4(e, i, c, t); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3) throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, Object a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, int a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, int a1, int a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(int a0, int a1, int a2, int a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, Object a2, long a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, Object a1, long a2, long a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(Object a0, long a1, long a2, long a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object targetA4(long a0, long a1, long a2, long a3) throws Throwable { return target(a0, a1, a2, a3); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(Object a0, Object a1, Object a2, int a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, Object a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(Object a0, Object a1, int a2, int a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(Object a0, Object a1, int a2, int a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, int a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, int a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, int a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(Object a0, int a1, int a2, int a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(Object a0, int a1, int a2, int a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(int a0, int a1, int a2, int a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(int a0, int a1, int a2, int a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(int a0, int a1, int a2, int a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(int a0, int a1, int a2, int a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(int a0, int a1, int a2, int a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(Object a0, Object a1, Object a2, long a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(Object a0, Object a1, long a2, long a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(Object a0, Object a1, long a2, long a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(Object a0, long a1, long a2, long a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(Object a0, long a1, long a2, long a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
+ protected float invoke_F(long a0, long a1, long a2, long a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
+ protected double invoke_D(long a0, long a1, long a2, long a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
+ }
+//params=[5, 5, 2, 99, 99, 99]
+ static class A5 extends Adapter {
+ protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A5(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A5 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A5(e, i, c, t); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, Object a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, int a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, int a1, int a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(int a0, int a1, int a2, int a3, int a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, Object a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, Object a2, long a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, Object a1, long a2, long a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(Object a0, long a1, long a2, long a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object targetA5(long a0, long a1, long a2, long a3, long a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, int a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, int a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, int a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, int a2, int a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, int a2, int a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, int a2, int a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, int a1, int a2, int a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, int a1, int a2, int a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, int a1, int a2, int a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(int a0, int a1, int a2, int a3, int a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(int a0, int a1, int a2, int a3, int a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(int a0, int a1, int a2, int a3, int a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
+ }
+//params=[6, 10, 2, 99, 0, 99]
+ static class A6 extends Adapter {
+ protected A6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A6(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A6 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A6(e, i, c, t); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, Object a2, Object a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, Object a2, long a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, Object a1, long a2, long a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(Object a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object targetA6(long a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
+ }
+ static class A7 extends Adapter {
+ protected A7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A7(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A7 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A7(e, i, c, t); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object targetA7(long a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
+ }
+ static class A8 extends Adapter {
+ protected A8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A8(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A8 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A8(e, i, c, t); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object targetA8(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
+ }
+ static class A9 extends Adapter {
+ protected A9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A9(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A9 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A9(e, i, c, t); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object targetA9(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
+ }
+ static class A10 extends Adapter {
+ protected A10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
+ protected A10(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
+ protected A10 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A10(e, i, c, t); }
+ protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object targetA10(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(Object a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected Object invoke_L(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected int invoke_I(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ protected long invoke_J(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/VolatileCallSite.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/VolatileCallSite.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+/**
+ * A {@code VolatileCallSite} is a {@link CallSite} whose target acts like a volatile variable.
+ * An {@code invokedynamic} instruction linked to a {@code VolatileCallSite} sees updates
+ * to its call site target immediately, even if the update occurs in another thread.
+ * There may be a performance penalty for such tight coupling between threads.
+ *
+ * Unlike {@code MutableCallSite}, there is no
+ * {@linkplain MutableCallSite#syncAll syncAll operation} on volatile
+ * call sites, since every write to a volatile variable is implicitly
+ * synchronized with reader threads.
+ *
+ * In other respects, a {@code VolatileCallSite} is interchangeable
+ * with {@code MutableCallSite}.
+ * @see MutableCallSite
+ * @author John Rose, JSR 292 EG
+ */
+public class VolatileCallSite extends CallSite {
+ /**
+ * Creates a call site with a volatile binding to its target.
+ * The initial target is set to a method handle
+ * of the given type which will throw an {@code IllegalStateException} if called.
+ * @param type the method type that this call site will have
+ * @throws NullPointerException if the proposed type is null
+ */
+ public VolatileCallSite(MethodType type) {
+ super(type);
+ }
+
+ /**
+ * Creates a call site with a volatile binding to its target.
+ * The target is set to the given value.
+ * @param target the method handle that will be the initial target of the call site
+ * @throws NullPointerException if the proposed target is null
+ */
+ public VolatileCallSite(MethodHandle target) {
+ super(target);
+ }
+
+ /**
+ * Returns the target method of the call site, which behaves
+ * like a {@code volatile} field of the {@code VolatileCallSite}.
+ *
+ * The interactions of {@code getTarget} with memory are the same
+ * as of a read from a {@code volatile} field.
+ *
+ * In particular, the current thread is required to issue a fresh
+ * read of the target from memory, and must not fail to see
+ * a recent update to the target by another thread.
+ *
+ * @return the linkage state of this call site, a method handle which can change over time
+ * @see #setTarget
+ */
+ @Override public final MethodHandle getTarget() {
+ return getTargetVolatile();
+ }
+
+ /**
+ * Updates the target method of this call site, as a volatile variable.
+ * The type of the new target must agree with the type of the old target.
+ *
+ * The interactions with memory are the same as of a write to a volatile field.
+ * In particular, any threads is guaranteed to see the updated target
+ * the next time it calls {@code getTarget}.
+ * @param newTarget the new target
+ * @throws NullPointerException if the proposed new target is null
+ * @throws WrongMethodTypeException if the proposed new target
+ * has a method type that differs from the previous target
+ * @see #getTarget
+ */
+ @Override public void setTarget(MethodHandle newTarget) {
+ checkTargetChange(getTargetVolatile(), newTarget);
+ setTargetVolatile(newTarget);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final MethodHandle dynamicInvoker() {
+ return makeDynamicInvoker();
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/WrongMethodTypeException.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/WrongMethodTypeException.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+package java.lang.invoke;
+
+/**
+ * Thrown to indicate that code has attempted to call a method handle
+ * via the wrong method type. As with the bytecode representation of
+ * normal Java method calls, method handle calls are strongly typed
+ * to a specific type descriptor associated with a call site.
+ *
+ * This exception may also be thrown when two method handles are
+ * composed, and the system detects that their types cannot be
+ * matched up correctly. This amounts to an early evaluation
+ * of the type mismatch, at method handle construction time,
+ * instead of when the mismatched method handle is called.
+ *
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class WrongMethodTypeException extends RuntimeException {
+ private static final long serialVersionUID = 292L;
+
+ /**
+ * Constructs a {@code WrongMethodTypeException} with no detail message.
+ */
+ public WrongMethodTypeException() {
+ super();
+ }
+
+ /**
+ * Constructs a {@code WrongMethodTypeException} with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public WrongMethodTypeException(String s) {
+ super(s);
+ }
+}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/lang/invoke/package-info.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/invoke/package-info.java Wed Jul 05 17:39:17 2017 +0200
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2008, 2011, 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.
+ */
+
+/**
+ * The {@code java.lang.invoke} package contains dynamic language support provided directly by
+ * the Java core class libraries and virtual machine.
+ *
+ *
+ * Certain types in this package have special relations to dynamic
+ * language support in the virtual machine:
+ *
+ * The class {@link java.lang.invoke.MethodHandle MethodHandle} contains
+ * signature polymorphic methods
+ * which can be linked regardless of their type descriptor.
+ * Normally, method linkage requires exact matching of type descriptors.
+ *
+ *
+ * The JVM bytecode format supports immediate constants of
+ * the classes {@link java.lang.invoke.MethodHandle MethodHandle} and {@link java.lang.invoke.MethodType MethodType}.
+ *
+ *
+ *
+ * Corresponding JVM bytecode format changes
+ * The following low-level information is presented here as a preview of
+ * changes being made to the Java Virtual Machine specification for JSR 292.
+ * This information will be incorporated in a future version of the JVM specification.
+ *
+ * {@code invokedynamic} instruction format
+ * In bytecode, an {@code invokedynamic} instruction is formatted as five bytes.
+ * The first byte is the opcode 186 (hexadecimal {@code BA}).
+ * The next two bytes are a constant pool index (in the same format as for the other {@code invoke} instructions).
+ * The final two bytes are reserved for future use and required to be zero.
+ * The constant pool reference of an {@code invokedynamic} instruction is to a entry
+ * with tag {@code CONSTANT_InvokeDynamic} (decimal 18). See below for its format.
+ * The entry specifies the following information:
+ *
+ * a bootstrap method (a {@link java.lang.invoke.MethodHandle MethodHandle} constant)
+ * the dynamic invocation name (a UTF8 string)
+ * the argument and return types of the call (encoded as a type descriptor in a UTF8 string)
+ * optionally, a sequence of additional static arguments to the bootstrap method ({@code ldc}-type constants)
+ *
+ *
+ * Each instance of an {@code invokedynamic} instruction is called a dynamic call site .
+ * Multiple instances of an {@code invokedynamic} instruction can share a single
+ * {@code CONSTANT_InvokeDynamic} entry.
+ * In any case, distinct call sites always have distinct linkage state.
+ *
+ * A dynamic call site is originally in an unlinked state. In this state, there is
+ * no target method for the call site to invoke.
+ * A dynamic call site is linked by means of a bootstrap method,
+ * as described below .
+ *
+ *
constant pool entries for {@code invokedynamic} instructions
+ * If a constant pool entry has the tag {@code CONSTANT_InvokeDynamic} (decimal 18),
+ * it must contain exactly four more bytes after the tag.
+ * These bytes are interpreted as two 16-bit indexes, in the usual {@code u2} format.
+ * The first pair of bytes after the tag must be an index into a side table called the
+ * bootstrap method table , which is stored in the {@code BootstrapMethods}
+ * attribute as described below .
+ * The second pair of bytes must be an index to a {@code CONSTANT_NameAndType}.
+ *
+ * The first index specifies a bootstrap method used by the associated dynamic call sites.
+ * The second index specifies the method name, argument types, and return type of the dynamic call site.
+ * The structure of such an entry is therefore analogous to a {@code CONSTANT_Methodref},
+ * except that the bootstrap method specifier reference replaces
+ * the {@code CONSTANT_Class} reference of a {@code CONSTANT_Methodref} entry.
+ *
+ *
constant pool entries for {@linkplain java.lang.invoke.MethodType method types}
+ * If a constant pool entry has the tag {@code CONSTANT_MethodType} (decimal 16),
+ * it must contain exactly two more bytes, which must be an index to a {@code CONSTANT_Utf8}
+ * entry which represents a method type descriptor.
+ *
+ * The JVM will ensure that on first
+ * execution of an {@code ldc} instruction for this entry, a {@link java.lang.invoke.MethodType MethodType}
+ * will be created which represents the type descriptor.
+ * Any classes mentioned in the {@code MethodType} will be loaded if necessary,
+ * but not initialized.
+ * Access checking and error reporting is performed exactly as it is for
+ * references by {@code ldc} instructions to {@code CONSTANT_Class} constants.
+ *
+ *
constant pool entries for {@linkplain java.lang.invoke.MethodHandle method handles}
+ * If a constant pool entry has the tag {@code CONSTANT_MethodHandle} (decimal 15),
+ * it must contain exactly three more bytes. The first byte after the tag is a subtag
+ * value which must be in the range 1 through 9, and the last two must be an index to a
+ * {@code CONSTANT_Fieldref}, {@code CONSTANT_Methodref}, or
+ * {@code CONSTANT_InterfaceMethodref} entry which represents a field or method
+ * for which a method handle is to be created.
+ * Furthermore, the subtag value and the type of the constant index value
+ * must agree according to the table below.
+ *
+ * The JVM will ensure that on first execution of an {@code ldc} instruction
+ * for this entry, a {@link java.lang.invoke.MethodHandle MethodHandle} will be created which represents
+ * the field or method reference, according to the specific mode implied by the subtag.
+ *
+ * As with {@code CONSTANT_Class} and {@code CONSTANT_MethodType} constants,
+ * the {@code Class} or {@code MethodType} object which reifies the field or method's
+ * type is created. Any classes mentioned in this reification will be loaded if necessary,
+ * but not initialized, and access checking and error reporting performed as usual.
+ *
+ * Unlike the reflective {@code Lookup} API, there are no security manager calls made
+ * when these constants are resolved.
+ *
+ * The method handle itself will have a type and behavior determined by the subtag as follows:
+ *
+ *
+ * N subtag name member MH type bytecode behavior lookup expression
+ * 1 REF_getField C.f:T (C)T getfield C.f:T
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findGetter findGetter(C.class,"f",T.class)}
+ * 2 REF_getStatic C.f:T ( )T getstatic C.f:T
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticGetter findStaticGetter(C.class,"f",T.class)}
+ * 3 REF_putField C.f:T (C,T)void putfield C.f:T
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findSetter findSetter(C.class,"f",T.class)}
+ * 4 REF_putStatic C.f:T (T)void putstatic C.f:T
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticSetter findStaticSetter(C.class,"f",T.class)}
+ * 5 REF_invokeVirtual C.m(A*)T (C,A*)T invokevirtual C.m(A*)T
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual findVirtual(C.class,"m",MT)}
+ * 6 REF_invokeStatic C.m(A*)T (C,A*)T invokestatic C.m(A*)T
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findStatic findStatic(C.class,"m",MT)}
+ * 7 REF_invokeSpecial C.m(A*)T (C,A*)T invokespecial C.m(A*)T
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findSpecial findSpecial(C.class,"m",MT,this.class)}
+ * 8 REF_newInvokeSpecial C.<init>(A*)void (A*)C new C; dup; invokespecial C.<init>(A*)void
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findConstructor findConstructor(C.class,MT)}
+ * 9 REF_invokeInterface C.m(A*)T (C,A*)T invokeinterface C.m(A*)T
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual findVirtual(C.class,"m",MT)}
+ *
+ *
+ * Here, the type {@code C} is taken from the {@code CONSTANT_Class} reference associated
+ * with the {@code CONSTANT_NameAndType} descriptor.
+ * The field name {@code f} or method name {@code m} is taken from the {@code CONSTANT_NameAndType}
+ * as is the result type {@code T} and (in the case of a method or constructor) the argument type sequence
+ * {@code A*}.
+ *
+ * Each method handle constant has an equivalent instruction sequence called its bytecode behavior .
+ * In general, creating a method handle constant can be done in exactly the same circumstances that
+ * the JVM would successfully resolve the symbolic references in the bytecode behavior.
+ * Also, the type of a method handle constant is such that a valid {@code invokeExact} call
+ * on the method handle has exactly the same JVM stack effects as the bytecode behavior .
+ * Finally, calling a method handle constant on a valid set of arguments has exactly the same effect
+ * and returns the same result (if any) as the corresponding bytecode behavior .
+ *
+ * Each method handle constant also has an equivalent reflective lookup expression ,
+ * which is a query to a method in {@link java.lang.invoke.MethodHandles.Lookup}.
+ * In the example lookup method expression given in the table above, the name {@code MT}
+ * stands for a {@code MethodType} built from {@code T} and the sequence of argument types {@code A*}.
+ * (Note that the type {@code C} is not prepended to the query type {@code MT} even if the member is non-static.)
+ * In the case of {@code findSpecial}, the name {@code this.class} refers to the class containing
+ * the bytecodes.
+ *
+ * The special name {@code } is not allowed.
+ * The special name {@code } is not allowed except for subtag 8 as shown.
+ *
+ * The JVM verifier and linker apply the same access checks and restrictions for these references as for the hypothetical
+ * bytecode instructions specified in the last column of the table.
+ * A method handle constant will successfully resolve to a method handle if the symbolic references
+ * of the corresponding bytecode instruction(s) would also resolve successfully.
+ * Otherwise, an attempt to resolve the constant will throw equivalent linkage errors.
+ * In particular, method handles to
+ * private and protected members can be created in exactly those classes for which the corresponding
+ * normal accesses are legal.
+ *
+ * A constant may refer to a method or constructor with the {@code varargs}
+ * bit (hexadecimal {@code 0x0080}) set in its modifier bitmask.
+ * The method handle constant produced for such a method behaves as if
+ * it were created by {@link java.lang.invoke.MethodHandle#asVarargsCollector asVarargsCollector}.
+ * In other words, the constant method handle will exhibit variable arity,
+ * when invoked via {@code invokeGeneric}.
+ * On the other hand, its behavior with respect to {@code invokeExact} will be the same
+ * as if the {@code varargs} bit were not set.
+ *
+ * Although the {@code CONSTANT_MethodHandle} and {@code CONSTANT_MethodType} constant types
+ * resolve class names, they do not force class initialization.
+ * Method handle constants for subtags {@code REF_getStatic}, {@code REF_putStatic}, and {@code REF_invokeStatic}
+ * may force class initialization on their first invocation, just like the corresponding bytecodes.
+ *
+ * The rules of section 5.4.3 of the
+ * JVM Specification
+ * apply to the resolution of {@code CONSTANT_MethodType}, {@code CONSTANT_MethodHandle},
+ * and {@code CONSTANT_InvokeDynamic} constants,
+ * by the execution of {@code invokedynamic} and {@code ldc} instructions.
+ * (Roughly speaking, this means that every use of a constant pool entry
+ * must lead to the same outcome.
+ * If the resolution succeeds, the same object reference is produced
+ * by every subsequent execution of the same instruction.
+ * If the resolution of the constant causes an error to occur,
+ * the same error will be re-thrown on every subsequent attempt
+ * to use this particular constant.)
+ *
+ * Constants created by the resolution of these constant pool types are not necessarily
+ * interned. Except for {@code CONSTANT_Class} and {@code CONSTANT_String} entries,
+ * two distinct constant pool entries might not resolve to the same reference
+ * even if they contain the same symbolic reference.
+ *
+ *
Bootstrap Methods
+ * Before the JVM can execute a dynamic call site (an {@code invokedynamic} instruction),
+ * the call site must first be linked .
+ * Linking is accomplished by calling a bootstrap method
+ * which is given the static information content of the call site,
+ * and which must produce a {@link java.lang.invoke.MethodHandle method handle}
+ * that gives the behavior of the call site.
+ *
+ * Each {@code invokedynamic} instruction statically specifies its own
+ * bootstrap method as a constant pool reference.
+ * The constant pool reference also specifies the call site's name and type descriptor,
+ * just like {@code invokevirtual} and the other invoke instructions.
+ *
+ * Linking starts with resolving the constant pool entry for the
+ * bootstrap method, and resolving a {@link java.lang.invoke.MethodType MethodType} object for
+ * the type descriptor of the dynamic call site.
+ * This resolution process may trigger class loading.
+ * It may therefore throw an error if a class fails to load.
+ * This error becomes the abnormal termination of the dynamic
+ * call site execution.
+ * Linkage does not trigger class initialization.
+ *
+ * Next, the bootstrap method call is started, with at least four values being stacked:
+ *
+ * a {@code MethodHandle}, the resolved bootstrap method itself
+ * a {@code MethodHandles.Lookup}, a lookup object on the caller class in which dynamic call site occurs
+ * a {@code String}, the method name mentioned in the call site
+ * a {@code MethodType}, the resolved type descriptor of the call
+ * optionally, one or more additional static arguments
+ *
+ * The method handle is then applied to the other values as if by
+ * {@link java.lang.invoke.MethodHandle#invokeGeneric invokeGeneric}.
+ * The returned result must be a {@link java.lang.invoke.CallSite CallSite} (or a subclass).
+ * The type of the call site's target must be exactly equal to the type
+ * derived from the dynamic call site's type descriptor and passed to
+ * the bootstrap method.
+ * The call site then becomes permanently linked to the dynamic call site.
+ *
+ * As long as each bootstrap method can be correctly invoked
+ * by invokeGeneric
, its detailed type is arbitrary.
+ * For example, the first argument could be {@code Object}
+ * instead of {@code MethodHandles.Lookup}, and the return type
+ * could also be {@code Object} instead of {@code CallSite}.
+ * (Note that the types and number of the stacked arguments limit
+ * the legal kinds of bootstrap methods to appropriately typed
+ * static methods and constructors of {@code CallSite} subclasses.)
+ *
+ * After resolution, the linkage process may fail in a variety of ways.
+ * All failures are reported by a {@link java.lang.BootstrapMethodError BootstrapMethodError},
+ * which is thrown as the abnormal termination of the dynamic call
+ * site execution.
+ * The following circumstances will cause this:
+ *
+ * the index to the bootstrap method specifier is out of range
+ * the bootstrap method cannot be resolved
+ * the {@code MethodType} to pass to the bootstrap method cannot be resolved
+ * a static argument to the bootstrap method cannot be resolved
+ * (i.e., a {@code CONSTANT_Class}, {@code CONSTANT_MethodType},
+ * or {@code CONSTANT_MethodHandle} argument cannot be linked)
+ * the bootstrap method has the wrong arity,
+ * causing {@code invokeGeneric} to throw {@code WrongMethodTypeException}
+ * the bootstrap method has a wrong argument or return type
+ * the bootstrap method invocation completes abnormally
+ * the result from the bootstrap invocation is not a reference to
+ * an object of type {@link java.lang.invoke.CallSite CallSite}
+ * the target of the {@code CallSite} does not have a target of
+ * the expected {@code MethodType}
+ *
+ *
+ * timing of linkage
+ * A dynamic call site is linked just before its first execution.
+ * The bootstrap method call implementing the linkage occurs within
+ * a thread that is attempting a first execution.
+ *
+ * If there are several such threads, the bootstrap method may be
+ * invoked in several threads concurrently.
+ * Therefore, bootstrap methods which access global application
+ * data must take the usual precautions against race conditions.
+ * In any case, every {@code invokedynamic} instruction is either
+ * unlinked or linked to a unique {@code CallSite} object.
+ *
+ * In an application which requires dynamic call sites with individually
+ * mutable behaviors, their bootstrap methods should produce distinct
+ * {@link java.lang.invoke.CallSite CallSite} objects, one for each linkage request.
+ * Alternatively, an application can link a single {@code CallSite} object
+ * to several {@code invokedynamic} instructions, in which case
+ * a change to the target method will become visible at each of
+ * the instructions.
+ *
+ * If several threads simultaneously execute a bootstrap method for a single dynamic
+ * call site, the JVM must choose one {@code CallSite} object and install it visibly to
+ * all threads. Any other bootstrap method calls are allowed to complete, but their
+ * results are ignored, and their dynamic call site invocations proceed with the originally
+ * chosen target object.
+ *
+ *
+ * Discussion:
+ * These rules do not enable the JVM to duplicate dynamic call sites,
+ * or to issue “causeless” bootstrap method calls.
+ * Every dynamic call site transitions at most once from unlinked to linked,
+ * just before its first invocation.
+ * There is no way to undo the effect of a completed bootstrap method call.
+ *
+ *
+ * Each {@code CONSTANT_InvokeDynamic} entry contains an index which references
+ * a bootstrap method specifier; all such specifiers are contained in a separate array.
+ * This array is defined by a class attribute named {@code BootstrapMethods}.
+ * The body of this attribute consists of a sequence of byte pairs, all interpreted as
+ * as 16-bit counts or constant pool indexes, in the {@code u2} format.
+ * The attribute body starts with a count of bootstrap method specifiers,
+ * which is immediately followed by the sequence of specifiers.
+ *
+ * Each bootstrap method specifier contains an index to a
+ * {@code CONSTANT_MethodHandle} constant, which is the bootstrap
+ * method itself.
+ * This is followed by a count, and then a sequence (perhaps empty) of
+ * indexes to additional static arguments
+ * for the bootstrap method.
+ *
+ * During class loading, the verifier must check the structure of the
+ * {@code BootstrapMethods} attribute. In particular, each constant
+ * pool index must be of the correct type. A bootstrap method index
+ * must refer to a {@code CONSTANT_MethodHandle} (tag 15).
+ * Every other index must refer to a valid operand of an
+ * {@code ldc_w} or {@code ldc2_w} instruction (tag 3..8 or 15..16).
+ *
+ *
+ * An {@code invokedynamic} instruction specifies at least three arguments
+ * to pass to its bootstrap method:
+ * The caller class (expressed as a {@link java.lang.invoke.MethodHandles.Lookup Lookup object},
+ * the name (extracted from the {@code CONSTANT_NameAndType} entry),
+ * and the type (also extracted from the {@code CONSTANT_NameAndType} entry).
+ * The {@code invokedynamic} instruction may specify additional metadata values
+ * to pass to its bootstrap method.
+ * Collectively, these values are called static arguments to the
+ * {@code invokedynamic} instruction, because they are used once at link
+ * time to determine the instruction's behavior on subsequent sets of
+ * dynamic arguments .
+ *
+ * Static arguments are used to communicate application-specific meta-data
+ * to the bootstrap method.
+ * Drawn from the constant pool, they may include references to classes, method handles,
+ * strings, or numeric data that may be relevant to the task of linking that particular call site.
+ *
+ * Static arguments are specified constant pool indexes stored in the {@code BootstrapMethods} attribute.
+ * Before the bootstrap method is invoked, each index is used to compute an {@code Object}
+ * reference to the indexed value in the constant pool.
+ * The valid constant pool entries are listed in this table:
+ *
+ *
+ * entry type argument type argument value
+ * CONSTANT_String java.lang.String
the indexed string literal
+ * CONSTANT_Class java.lang.Class
the indexed class, resolved
+ * CONSTANT_Integer java.lang.Integer
the indexed int value
+ * CONSTANT_Long java.lang.Long
the indexed long value
+ * CONSTANT_Float java.lang.Float
the indexed float value
+ * CONSTANT_Double java.lang.Double
the indexed double value
+ * CONSTANT_MethodHandle java.lang.invoke.MethodHandle
the indexed method handle constant
+ * CONSTANT_MethodType java.lang.invoke.MethodType
the indexed method type constant
+ *
+ *
+ *
+ * If a given {@code invokedynamic} instruction specifies no static arguments,
+ * the instruction's bootstrap method will be invoked on three arguments,
+ * conveying the instruction's caller class, name, and method type.
+ * If the {@code invokedynamic} instruction specifies one or more static arguments,
+ * those values will be passed as additional arguments to the method handle.
+ * (Note that because there is a limit of 255 arguments to any method,
+ * at most 252 extra arguments can be supplied.)
+ * The bootstrap method will be invoked as if by either {@code invokeGeneric}
+ * or {@code invokeWithArguments}. (There is no way to tell the difference.)
+ *
+ * The normal argument conversion rules for {@code invokeGeneric} apply to all stacked arguments.
+ * For example, if a pushed value is a primitive type, it may be converted to a reference by boxing conversion.
+ * If the bootstrap method is a variable arity method (its modifier bit {@code 0x0080} is set),
+ * then some or all of the arguments specified here may be collected into a trailing array parameter.
+ * (This is not a special rule, but rather a useful consequence of the interaction
+ * between {@code CONSTANT_MethodHandle} constants, the modifier bit for variable arity methods,
+ * and the {@code java.lang.invoke.MethodHandle#asVarargsCollector asVarargsCollector} transformation.)
+ *
+ * Given these rules, here are examples of legal bootstrap method declarations,
+ * given various numbers {@code N} of extra arguments.
+ * The first rows (marked {@code *}) will work for any number of extra arguments.
+ *
+ *
+ * N sample bootstrap method
+ * * CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
+ * * CallSite bootstrap(Object... args)
+ * * CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs)
+ * 0 CallSite bootstrap(Lookup caller, String name, MethodType type)
+ * 0 CallSite bootstrap(Lookup caller, Object... nameAndType)
+ * 1 CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg)
+ * 2 CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
+ * 2 CallSite bootstrap(Lookup caller, String name, MethodType type, String... args)
+ * 2 CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y)
+ *
+ *
+ * The last example assumes that the extra arguments are of type
+ * {@code CONSTANT_String} and {@code CONSTANT_Integer}, respectively.
+ * The second-to-last example assumes that all extra arguments are of type
+ * {@code CONSTANT_String}.
+ * The other examples work with all types of extra arguments.
+ *
+ * As noted above, the actual method type of the bootstrap method can vary.
+ * For example, the fourth argument could be {@code MethodHandle},
+ * if that is the type of the corresponding constant in
+ * the {@code CONSTANT_InvokeDynamic} entry.
+ * In that case, the {@code invokeGeneric} call will pass the extra method handle
+ * constant as an {@code Object}, but the type matching machinery of {@code invokeGeneric}
+ * will cast the reference back to {@code MethodHandle} before invoking the bootstrap method.
+ * (If a string constant were passed instead, by badly generated code, that cast would then fail,
+ * resulting in a {@code BootstrapMethodError}.)
+ *
+ * Extra bootstrap method arguments are intended to allow language implementors
+ * to safely and compactly encode metadata.
+ * In principle, the name and extra arguments are redundant,
+ * since each call site could be given its own unique bootstrap method.
+ * Such a practice is likely to produce large class files and constant pools.
+ *
+ *
Structure Summary
+ * // summary of constant and attribute structures
+struct CONSTANT_MethodHandle_info {
+ u1 tag = 15;
+ u1 reference_kind; // 1..8 (one of REF_invokeVirtual, etc.)
+ u2 reference_index; // index to CONSTANT_Fieldref or *Methodref
+}
+struct CONSTANT_MethodType_info {
+ u1 tag = 16;
+ u2 descriptor_index; // index to CONSTANT_Utf8, as in NameAndType
+}
+struct CONSTANT_InvokeDynamic_info {
+ u1 tag = 18;
+ u2 bootstrap_method_attr_index; // index into BootstrapMethods_attr
+ u2 name_and_type_index; // index to CONSTANT_NameAndType, as in Methodref
+}
+struct BootstrapMethods_attr {
+ u2 name; // CONSTANT_Utf8 = "BootstrapMethods"
+ u4 size;
+ u2 bootstrap_method_count;
+ struct bootstrap_method_specifier {
+ u2 bootstrap_method_ref; // index to CONSTANT_MethodHandle
+ u2 bootstrap_argument_count;
+ u2 bootstrap_arguments[bootstrap_argument_count]; // constant pool indexes
+ } bootstrap_methods[bootstrap_method_count];
+}
+ *
+ *
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+
+package java.lang.invoke;
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
--- a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Wed Jul 05 17:39:17 2017 +0200
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.Enumeration;
+import sun.net.ResourceManager;
/**
* Abstract datagram and multicast socket implementation base class.
@@ -66,7 +67,14 @@
*/
protected synchronized void create() throws SocketException {
fd = new FileDescriptor();
- datagramSocketCreate();
+ ResourceManager.beforeUdpCreate();
+ try {
+ datagramSocketCreate();
+ } catch (SocketException ioe) {
+ ResourceManager.afterUdpClose();
+ fd = null;
+ throw ioe;
+ }
}
/**
@@ -211,6 +219,7 @@
protected void close() {
if (fd != null) {
datagramSocketClose();
+ ResourceManager.afterUdpClose();
fd = null;
}
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java
--- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java Wed Jul 05 17:39:17 2017 +0200
@@ -32,6 +32,7 @@
import sun.net.ConnectionResetException;
import sun.net.NetHooks;
+import sun.net.ResourceManager;
/**
* Default Socket Implementation. This implementation does
@@ -68,6 +69,10 @@
private int resetState;
private final Object resetLock = new Object();
+ /* whether this Socket is a stream (TCP) socket or not (UDP)
+ */
+ private boolean stream;
+
/**
* Load net library into runtime.
*/
@@ -82,7 +87,19 @@
*/
protected synchronized void create(boolean stream) throws IOException {
fd = new FileDescriptor();
- socketCreate(stream);
+ this.stream = stream;
+ if (!stream) {
+ ResourceManager.beforeUdpCreate();
+ try {
+ socketCreate(false);
+ } catch (IOException ioe) {
+ ResourceManager.afterUdpClose();
+ fd = null;
+ throw ioe;
+ }
+ } else {
+ socketCreate(true);
+ }
if (socket != null)
socket.setCreated();
if (serverSocket != null)
@@ -479,6 +496,9 @@
protected void close() throws IOException {
synchronized(fdLock) {
if (fd != null) {
+ if (!stream) {
+ ResourceManager.afterUdpClose();
+ }
if (fdUseCount == 0) {
if (closePending) {
return;
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/net/URI.java
--- a/jdk/src/share/classes/java/net/URI.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/net/URI.java Wed Jul 05 17:39:17 2017 +0200
@@ -1829,21 +1829,23 @@
} else if (authority != null) {
sb.append("//");
if (authority.startsWith("[")) {
+ // authority should (but may not) contain an embedded IPv6 address
int end = authority.indexOf("]");
- if (end != -1 && authority.indexOf(":")!=-1) {
- String doquote, dontquote;
+ String doquote = authority, dontquote = "";
+ if (end != -1 && authority.indexOf(":") != -1) {
+ // the authority contains an IPv6 address
if (end == authority.length()) {
dontquote = authority;
doquote = "";
} else {
- dontquote = authority.substring(0,end+1);
- doquote = authority.substring(end+1);
+ dontquote = authority.substring(0 , end + 1);
+ doquote = authority.substring(end + 1);
}
- sb.append (dontquote);
- sb.append(quote(doquote,
+ }
+ sb.append(dontquote);
+ sb.append(quote(doquote,
L_REG_NAME | L_SERVER,
H_REG_NAME | H_SERVER));
- }
} else {
sb.append(quote(authority,
L_REG_NAME | L_SERVER,
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/net/URLConnection.java
--- a/jdk/src/share/classes/java/net/URLConnection.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/net/URLConnection.java Wed Jul 05 17:39:17 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2011, 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
@@ -1422,7 +1422,7 @@
if (!is.markSupported())
return null;
- is.mark(12);
+ is.mark(16);
int c1 = is.read();
int c2 = is.read();
int c3 = is.read();
@@ -1434,6 +1434,11 @@
int c9 = is.read();
int c10 = is.read();
int c11 = is.read();
+ int c12 = is.read();
+ int c13 = is.read();
+ int c14 = is.read();
+ int c15 = is.read();
+ int c16 = is.read();
is.reset();
if (c1 == 0xCA && c2 == 0xFE && c3 == 0xBA && c4 == 0xBE) {
@@ -1461,6 +1466,13 @@
}
}
+ // big and little (identical) endian UTF-8 encodings, with BOM
+ if (c1 == 0xef && c2 == 0xbb && c3 == 0xbf) {
+ if (c4 == '<' && c5 == '?' && c6 == 'x') {
+ return "application/xml";
+ }
+ }
+
// big and little endian UTF-16 encodings, with byte order mark
if (c1 == 0xfe && c2 == 0xff) {
if (c3 == 0 && c4 == '<' && c5 == 0 && c6 == '?' &&
@@ -1476,6 +1488,23 @@
}
}
+ // big and little endian UTF-32 encodings, with BOM
+ if (c1 == 0x00 && c2 == 0x00 && c3 == 0xfe && c4 == 0xff) {
+ if (c5 == 0 && c6 == 0 && c7 == 0 && c8 == '<' &&
+ c9 == 0 && c10 == 0 && c11 == 0 && c12 == '?' &&
+ c13 == 0 && c14 == 0 && c15 == 0 && c16 == 'x') {
+ return "application/xml";
+ }
+ }
+
+ if (c1 == 0xff && c2 == 0xfe && c3 == 0x00 && c4 == 0x00) {
+ if (c5 == '<' && c6 == 0 && c7 == 0 && c8 == 0 &&
+ c9 == '?' && c10 == 0 && c11 == 0 && c12 == 0 &&
+ c13 == 'x' && c14 == 0 && c15 == 0 && c16 == 0) {
+ return "application/xml";
+ }
+ }
+
if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') {
return "image/gif";
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/nio/file/Files.java
--- a/jdk/src/share/classes/java/nio/file/Files.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/Files.java Wed Jul 05 17:39:17 2017 +0200
@@ -1712,10 +1712,10 @@
* @return the {@code path} parameter
*
* @throws UnsupportedOperationException
- * if the attribute view is not available or it does not support
- * updating the attribute
+ * if the attribute view is not available
* @throws IllegalArgumentException
- * if the attribute value is of the correct type but has an
+ * if the attribute name is not specified, or is not recognized, or
+ * the attribute value is of the correct type but has an
* inappropriate value
* @throws ClassCastException
* if the attribute value is not of the expected type or is a
@@ -1776,9 +1776,12 @@
* @param options
* options indicating how symbolic links are handled
*
- * @return the attribute value or {@code null} if the attribute view
- * is not available or it does not support reading the attribute
+ * @return the attribute value
*
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available
+ * @throws IllegalArgumentException
+ * if the attribute name is not specified or is not recognized
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
@@ -1794,8 +1797,9 @@
{
// only one attribute should be read
if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
- return null;
+ throw new IllegalArgumentException(attribute);
Map map = readAttributes(path, attribute, options);
+ assert map.size() == 1;
String name;
int pos = attribute.indexOf(':');
if (pos == -1) {
@@ -1868,9 +1872,14 @@
* @param options
* options indicating how symbolic links are handled
*
- * @return a map of the attributes returned; may be empty. The map's keys
- * are the attribute names, its values are the attribute values
+ * @return a map of the attributes returned; The map's keys are the
+ * attribute names, its values are the attribute values
*
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available
+ * @throws IllegalArgumentException
+ * if no attributes are specified or an unrecognized attributes is
+ * specified
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/nio/file/Path.java
--- a/jdk/src/share/classes/java/nio/file/Path.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/Path.java Wed Jul 05 17:39:17 2017 +0200
@@ -228,6 +228,9 @@
* not have a root component and the given path has a root component then
* this path does not start with the given path.
*
+ * If the given path is associated with a different {@code FileSystem}
+ * to this path then {@code false} is returned.
+ *
* @param other
* the given path
*
@@ -270,6 +273,9 @@
* does not have a root component and the given path has a root component
* then this path does not end with the given path.
*
+ *
If the given path is associated with a different {@code FileSystem}
+ * to this path then {@code false} is returned.
+ *
* @param other
* the given path
*
@@ -283,7 +289,10 @@
* the given path string, in exactly the manner specified by the {@link
* #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path
* "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does
- * not end with "{@code r}" or "{@code /bar}".
+ * not end with "{@code r}" or "{@code /bar}". Note that trailing separators
+ * are not taken into account, and so invoking this method on the {@code
+ * Path}"{@code foo/bar}" with the {@code String} "{@code bar/}" returns
+ * {@code true}.
*
* @param other
* the given path string
@@ -724,12 +733,18 @@
* provider, platform specific. This method does not access the file system
* and neither file is required to exist.
*
+ *
This method may not be used to compare paths that are associated
+ * with different file system providers.
+ *
* @param other the path compared to this path.
*
* @return zero if the argument is {@link #equals equal} to this path, a
* value less than zero if this path is lexicographically less than
* the argument, or a value greater than zero if this path is
* lexicographically greater than the argument
+ *
+ * @throws ClassCastException
+ * if the paths are associated with different providers
*/
@Override
int compareTo(Path other);
@@ -738,7 +753,7 @@
* Tests this path for equality with the given object.
*
*
If the given object is not a Path, or is a Path associated with a
- * different provider, then this method immediately returns {@code false}.
+ * different {@code FileSystem}, then this method returns {@code false}.
*
*
Whether or not two path are equal depends on the file system
* implementation. In some cases the paths are compared without regard
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/nio/file/WatchKey.java
--- a/jdk/src/share/classes/java/nio/file/WatchKey.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/WatchKey.java Wed Jul 05 17:39:17 2017 +0200
@@ -146,5 +146,5 @@
*
* @return the object for which this watch key was created
*/
- //T watchable();
+ Watchable watchable();
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/nio/file/attribute/FileTime.java
--- a/jdk/src/share/classes/java/nio/file/attribute/FileTime.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/attribute/FileTime.java Wed Jul 05 17:39:17 2017 +0200
@@ -216,12 +216,14 @@
* "2009-02-13T23:31:30Z"}, and {@code FileTime.fromMillis(1234567890123L).toString()}
* yields {@code "2009-02-13T23:31:30.123Z"}.
*
- *
A {@code FileTime} is primarly intended to represent the value of a
+ *
A {@code FileTime} is primarily intended to represent the value of a
* file's time stamp. Where used to represent extreme values , where
* the year is less than "{@code 0001}" or greater than "{@code 9999}" then
- * the year may be expanded to more than four digits and may be
- * negative-signed. If more than four digits then leading zeros are not
- * present. The year before "{@code 0001}" is "{@code -0001}".
+ * this method deviates from ISO 8601 in the same manner as the
+ * XML Schema
+ * language . That is, the year may be expanded to more than four digits
+ * and may be negative-signed. If more than four digits then leading zeros
+ * are not present. The year before "{@code 0001}" is "{@code -0001}".
*
* @return the string representation of this file time
*/
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java
--- a/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/spi/FileSystemProvider.java Wed Jul 05 17:39:17 2017 +0200
@@ -1037,6 +1037,11 @@
* @return a map of the attributes returned; may be empty. The map's keys
* are the attribute names, its values are the attribute values
*
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available
+ * @throws IllegalArgumentException
+ * if no attributes are specified or an unrecognized attributes is
+ * specified
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
@@ -1064,10 +1069,10 @@
* options indicating how symbolic links are handled
*
* @throws UnsupportedOperationException
- * if the attribute view is not available or it does not support
- * updating the attribute
+ * if the attribute view is not available
* @throws IllegalArgumentException
- * if the attribute value is of the correct type but has an
+ * if the attribute name is not specified, or is not recognized, or
+ * the attribute value is of the correct type but has an
* inappropriate value
* @throws ClassCastException
* If the attribute value is not of the expected type or is a
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/security/AccessControlContext.java
--- a/jdk/src/share/classes/java/security/AccessControlContext.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/security/AccessControlContext.java Wed Jul 05 17:39:17 2017 +0200
@@ -29,6 +29,9 @@
import java.util.List;
import sun.security.util.Debug;
import sun.security.util.SecurityConstants;
+import sun.misc.JavaSecurityAccess;
+import sun.misc.SharedSecrets;
+
/**
* An AccessControlContext is used to make system resource access decisions
@@ -197,6 +200,24 @@
}
/**
+ * Constructor for JavaSecurityAccess.doIntersectionPrivilege()
+ */
+ AccessControlContext(ProtectionDomain[] context,
+ AccessControlContext privilegedContext)
+ {
+ this.context = context;
+ this.privilegedContext = privilegedContext;
+ this.isPrivileged = true;
+ }
+
+ /**
+ * Returns this context's context.
+ */
+ ProtectionDomain[] getContext() {
+ return context;
+ }
+
+ /**
* Returns true if this context is privileged.
*/
boolean isPrivileged()
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/security/CodeSource.java
--- a/jdk/src/share/classes/java/security/CodeSource.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/security/CodeSource.java Wed Jul 05 17:39:17 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -578,7 +578,7 @@
// Deserialize array of code signers (if any)
try {
- this.signers = (CodeSigner[])ois.readObject();
+ this.signers = ((CodeSigner[])ois.readObject()).clone();
} catch (IOException ioe) {
// no signers present
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/security/ProtectionDomain.java
--- a/jdk/src/share/classes/java/security/ProtectionDomain.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/security/ProtectionDomain.java Wed Jul 05 17:39:17 2017 +0200
@@ -36,6 +36,8 @@
import sun.misc.SharedSecrets;
import sun.security.util.Debug;
import sun.security.util.SecurityConstants;
+import sun.misc.JavaSecurityAccess;
+import sun.misc.SharedSecrets;
/**
*
@@ -59,6 +61,36 @@
public class ProtectionDomain {
+ static {
+ // Set up JavaSecurityAccess in SharedSecrets
+ SharedSecrets.setJavaSecurityAccess(
+ new JavaSecurityAccess() {
+ public T doIntersectionPrivilege(
+ PrivilegedAction action,
+ final AccessControlContext stack,
+ final AccessControlContext context)
+ {
+ if (action == null) {
+ throw new NullPointerException();
+ }
+ return AccessController.doPrivileged(
+ action,
+ new AccessControlContext(
+ stack.getContext(), context).optimize()
+ );
+ }
+
+ public T doIntersectionPrivilege(
+ PrivilegedAction action,
+ AccessControlContext context)
+ {
+ return doIntersectionPrivilege(action,
+ AccessController.getContext(), context);
+ }
+ }
+ );
+ }
+
/* CodeSource */
private CodeSource codesource ;
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/security/Timestamp.java
--- a/jdk/src/share/classes/java/security/Timestamp.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/security/Timestamp.java Wed Jul 05 17:39:17 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -157,7 +157,8 @@
// Explicitly reset hash code value to -1
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
- ois.defaultReadObject();
- myhash = -1;
+ ois.defaultReadObject();
+ myhash = -1;
+ timestamp = new Date(timestamp.getTime());
}
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/sql/DriverManager.java
--- a/jdk/src/share/classes/java/sql/DriverManager.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/sql/DriverManager.java Wed Jul 05 17:39:17 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, 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
@@ -26,10 +26,10 @@
package java.sql;
import java.util.Iterator;
-import java.sql.Driver;
import java.util.ServiceLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -79,6 +79,27 @@
public class DriverManager {
+ // List of registered JDBC drivers
+ private final static CopyOnWriteArrayList registeredDrivers = new CopyOnWriteArrayList();
+ private static volatile int loginTimeout = 0;
+ private static volatile java.io.PrintWriter logWriter = null;
+ private static volatile java.io.PrintStream logStream = null;
+ // Used in println() to synchronize logWriter
+ private final static Object logSync = new Object();
+
+ /* Prevent the DriverManager class from being instantiated. */
+ private DriverManager(){}
+
+
+ /**
+ * Load the initial JDBC drivers by checking the System property
+ * jdbc.properties and then use the {@code ServiceLoader} mechanism
+ */
+ static {
+ loadInitialDrivers();
+ println("JDBC DriverManager initialized");
+ }
+
/**
* The SQLPermission
constant that allows the
* setting of the logging stream.
@@ -235,44 +256,33 @@
*/
public static Driver getDriver(String url)
throws SQLException {
- java.util.Vector drivers = null;
println("DriverManager.getDriver(\"" + url + "\")");
- if (!initialized) {
- initialize();
- }
-
- synchronized (DriverManager.class){
- // use the read copy of the drivers vector
- drivers = readDrivers;
- }
-
// Gets the classloader of the code that called this method, may
// be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
- // Walk through the loaded drivers attempting to locate someone
+ // Walk through the loaded registeredDrivers attempting to locate someone
// who understands the given URL.
- for (int i = 0; i < drivers.size(); i++) {
- DriverInfo di = (DriverInfo)drivers.elementAt(i);
+ for (Driver aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if ( getCallerClass(callerCL, di.driverClassName ) !=
- di.driverClass ) {
- println(" skipping: " + di);
- continue;
+ if(isDriverAllowed(aDriver, callerCL)) {
+ try {
+ if(aDriver.acceptsURL(url)) {
+ // Success!
+ println("getDriver returning " + aDriver.getClass().getName());
+ return (aDriver);
+ }
+
+ } catch(SQLException sqe) {
+ // Drop through and try the next driver.
+ }
+ } else {
+ println(" skipping: " + aDriver.getClass().getName());
}
- try {
- println(" trying " + di);
- if (di.driver.acceptsURL(url)) {
- // Success!
- println("getDriver returning " + di);
- return (di.driver);
- }
- } catch (SQLException ex) {
- // Drop through and try the next driver.
- }
+
}
println("getDriver: no suitable driver");
@@ -292,23 +302,16 @@
*/
public static synchronized void registerDriver(java.sql.Driver driver)
throws SQLException {
- if (!initialized) {
- initialize();
+
+ /* Register the driver if it has not already been added to our list */
+ if(driver != null) {
+ registeredDrivers.addIfAbsent(driver);
+ } else {
+ // This is for compatibility with the original DriverManager
+ throw new NullPointerException();
}
- DriverInfo di = new DriverInfo();
-
- di.driver = driver;
- di.driverClass = driver.getClass();
- di.driverClassName = di.driverClass.getName();
-
- // Not Required -- drivers.addElement(di);
-
- writeDrivers.addElement(di);
- println("registerDriver: " + di);
-
- /* update the read copy of drivers vector */
- readDrivers = (java.util.Vector) writeDrivers.clone();
+ println("registerDriver: " + driver);
}
@@ -321,37 +324,26 @@
*/
public static synchronized void deregisterDriver(Driver driver)
throws SQLException {
+ if (driver == null) {
+ return;
+ }
+
// Gets the classloader of the code that called this method,
// may be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
println("DriverManager.deregisterDriver: " + driver);
- // Walk through the loaded drivers.
- int i;
- DriverInfo di = null;
- for (i = 0; i < writeDrivers.size(); i++) {
- di = (DriverInfo)writeDrivers.elementAt(i);
- if (di.driver == driver) {
- break;
+ if(registeredDrivers.contains(driver)) {
+ if (isDriverAllowed(driver, callerCL)) {
+ registeredDrivers.remove(driver);
+ } else {
+ // If the caller does not have permission to load the driver then
+ // throw a SecurityException.
+ throw new SecurityException();
}
- }
- // If we can't find the driver just return.
- if (i >= writeDrivers.size()) {
+ } else {
println(" couldn't find driver to unload");
- return;
}
-
- // If the caller does not have permission to load the driver then
- // throw a security exception.
- if (getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {
- throw new SecurityException();
- }
-
- // Remove the driver. Other entries in drivers get shuffled down.
- writeDrivers.removeElementAt(i);
-
- /* update the read copy of drivers vector */
- readDrivers = (java.util.Vector) writeDrivers.clone();
}
/**
@@ -364,34 +356,22 @@
* @return the list of JDBC Drivers loaded by the caller's class loader
*/
public static java.util.Enumeration getDrivers() {
- java.util.Vector result = new java.util.Vector<>();
- java.util.Vector drivers = null;
-
- if (!initialized) {
- initialize();
- }
-
- synchronized (DriverManager.class){
- // use the readcopy of drivers
- drivers = readDrivers;
- }
+ java.util.Vector result = new java.util.Vector();
// Gets the classloader of the code that called this method, may
// be null.
ClassLoader callerCL = DriverManager.getCallerClassLoader();
- // Walk through the loaded drivers.
- for (int i = 0; i < drivers.size(); i++) {
- DriverInfo di = (DriverInfo)drivers.elementAt(i);
+ // Walk through the loaded registeredDrivers.
+ for(Driver aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {
- println(" skipping: " + di);
- continue;
+ if(isDriverAllowed(aDriver, callerCL)) {
+ result.addElement(aDriver);
+ } else {
+ println(" skipping: " + aDriver.getClass().getName());
}
- result.addElement(di.driver);
}
-
return (result.elements());
}
@@ -481,21 +461,22 @@
//------------------------------------------------------------------------
- // Returns the class object that would be created if the code calling the
- // driver manager had loaded the driver class, or null if the class
- // is inaccessible.
- private static Class getCallerClass(ClassLoader callerClassLoader,
- String driverClassName) {
- Class callerC = null;
+ // Indicates whether the class object that would be created if the code calling
+ // DriverManager is accessible.
+ private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
+ boolean result = false;
+ if(driver != null) {
+ Class> aClass = null;
+ try {
+ aClass = Class.forName(driver.getClass().getName(), true, classLoader);
+ } catch (Exception ex) {
+ result = false;
+ }
- try {
- callerC = Class.forName(driverClassName, true, callerClassLoader);
- }
- catch (Exception ex) {
- callerC = null; // being very careful
+ result = ( aClass == driver.getClass() ) ? true : false;
}
- return callerC;
+ return result;
}
private static void loadInitialDrivers() {
@@ -544,26 +525,17 @@
});
println("DriverManager.initialize: jdbc.drivers = " + drivers);
- if (drivers == null) {
+
+ if (drivers == null || drivers.equals("")) {
return;
}
- while (drivers.length() != 0) {
- int x = drivers.indexOf(':');
- String driver;
- if (x < 0) {
- driver = drivers;
- drivers = "";
- } else {
- driver = drivers.substring(0, x);
- drivers = drivers.substring(x+1);
- }
- if (driver.length() == 0) {
- continue;
- }
+ String[] driversList = drivers.split(":");
+ println("number of Drivers:" + driversList.length);
+ for (String aDriver : driversList) {
try {
- println("DriverManager.Initialize: loading " + driver);
- Class.forName(driver, true,
- ClassLoader.getSystemClassLoader());
+ println("DriverManager.Initialize: loading " + aDriver);
+ Class.forName(aDriver, true,
+ ClassLoader.getSystemClassLoader());
} catch (Exception ex) {
println("DriverManager.Initialize: load failed: " + ex);
}
@@ -574,7 +546,6 @@
// Worker method called by the public getConnection() methods.
private static Connection getConnection(
String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
- java.util.Vector drivers = null;
/*
* When callerCl is null, we should check the application's
* (which is invoking this class indirectly)
@@ -594,40 +565,32 @@
println("DriverManager.getConnection(\"" + url + "\")");
- if (!initialized) {
- initialize();
- }
-
- synchronized (DriverManager.class){
- // use the readcopy of drivers
- drivers = readDrivers;
- }
-
- // Walk through the loaded drivers attempting to make a connection.
+ // Walk through the loaded registeredDrivers attempting to make a connection.
// Remember the first exception that gets raised so we can reraise it.
SQLException reason = null;
- for (int i = 0; i < drivers.size(); i++) {
- DriverInfo di = (DriverInfo)drivers.elementAt(i);
+ for(Driver aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {
- println(" skipping: " + di);
- continue;
+ if(isDriverAllowed(aDriver, callerCL)) {
+ try {
+ println(" trying " + aDriver.getClass().getName());
+ Connection con = aDriver.connect(url, info);
+ if (con != null) {
+ // Success!
+ println("getConnection returning " + aDriver.getClass().getName());
+ return (con);
+ }
+ } catch (SQLException ex) {
+ if (reason == null) {
+ reason = ex;
+ }
+ }
+
+ } else {
+ println(" skipping: " + aDriver.getClass().getName());
}
- try {
- println(" trying " + di);
- Connection result = di.driver.connect(url, info);
- if (result != null) {
- // Success!
- println("getConnection returning " + di);
- return (result);
- }
- } catch (SQLException ex) {
- if (reason == null) {
- reason = ex;
- }
- }
+
}
// if we got here nobody could connect.
@@ -640,45 +603,7 @@
throw new SQLException("No suitable driver found for "+ url, "08001");
}
-
- // Class initialization.
- static void initialize() {
- if (initialized) {
- return;
- }
- initialized = true;
- loadInitialDrivers();
- println("JDBC DriverManager initialized");
- }
-
- /* Prevent the DriverManager class from being instantiated. */
- private DriverManager(){}
-
- /* write copy of the drivers vector */
- private static java.util.Vector writeDrivers = new java.util.Vector();
-
- /* write copy of the drivers vector */
- private static java.util.Vector readDrivers = new java.util.Vector();
-
- private static int loginTimeout = 0;
- private static java.io.PrintWriter logWriter = null;
- private static java.io.PrintStream logStream = null;
- private static boolean initialized = false;
-
- private static Object logSync = new Object();
-
/* Returns the caller's class loader, or null if none */
private static native ClassLoader getCallerClassLoader();
}
-
-// DriverInfo is a package-private support class.
-class DriverInfo {
- Driver driver;
- Class driverClass;
- String driverClassName;
-
- public String toString() {
- return ("driver[className=" + driverClassName + "," + driver + "]");
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/Formatter.java
--- a/jdk/src/share/classes/java/util/Formatter.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/Formatter.java Wed Jul 05 17:39:17 2017 +0200
@@ -1401,10 +1401,9 @@
* The number of digits in the result for the fractional part of
* m or a is equal to the precision. If the precision is not
* specified then the default value is {@code 6}. If the precision is
- * less than the number of digits which would appear after the decimal
- * point in the string returned by {@link Float#toString(float)} or {@link
- * Double#toString(double)} respectively, then the value will be rounded
- * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
+ * less than the number of digits to the right of the decimal point then
+ * the value will be rounded using the
+ * {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
* algorithm}. Otherwise, zeros may be appended to reach the precision.
* For a canonical representation of the value, use {@link
* BigDecimal#toString()}.
@@ -1463,12 +1462,11 @@
* more decimal digits representing the fractional part of m .
*
*
The number of digits in the result for the fractional part of
- * m or a is equal to the precision. If the precision is not
+ * m or a is equal to the precision. If the precision is not
* specified then the default value is {@code 6}. If the precision is
- * less than the number of digits which would appear after the decimal
- * point in the string returned by {@link Float#toString(float)} or {@link
- * Double#toString(double)} respectively, then the value will be rounded
- * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
+ * less than the number of digits to the right of the decimal point
+ * then the value will be rounded using the
+ * {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
* algorithm}. Otherwise, zeros may be appended to reach the precision.
* For a canonical representation of the value, use {@link
* BigDecimal#toString()}.
@@ -3585,7 +3583,7 @@
int scale = value.scale();
if (scale > prec) {
- // more "scale" digits than the requested "precision
+ // more "scale" digits than the requested "precision"
int compPrec = value.precision();
if (compPrec <= scale) {
// case of 0.xxxxxx
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/JumboEnumSet.java
--- a/jdk/src/share/classes/java/util/JumboEnumSet.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/JumboEnumSet.java Wed Jul 05 17:39:17 2017 +0200
@@ -34,6 +34,8 @@
* @serial exclude
*/
class JumboEnumSet> extends EnumSet {
+ private static final long serialVersionUID = 334349849919042784L;
+
/**
* Bit vector representation of this set. The ith bit of the jth
* element of this array represents the presence of universe[64*j +i]
@@ -138,8 +140,11 @@
public void remove() {
if (lastReturned == 0)
throw new IllegalStateException();
- elements[lastReturnedIndex] -= lastReturned;
- size--;
+ final long oldElements = elements[lastReturnedIndex];
+ elements[lastReturnedIndex] &= ~lastReturned;
+ if (oldElements != elements[lastReturnedIndex]) {
+ size--;
+ }
lastReturned = 0;
}
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/Locale.java
--- a/jdk/src/share/classes/java/util/Locale.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/Locale.java Wed Jul 05 17:39:17 2017 +0200
@@ -1168,7 +1168,7 @@
boolean e = (_extensions.getID().length() != 0);
StringBuilder result = new StringBuilder(_baseLocale.getLanguage());
- if (r || (l && v)) {
+ if (r || (l && (v || s || e))) {
result.append('_')
.append(_baseLocale.getRegion()); // This may just append '_'
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/RegularEnumSet.java
--- a/jdk/src/share/classes/java/util/RegularEnumSet.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/RegularEnumSet.java Wed Jul 05 17:39:17 2017 +0200
@@ -34,6 +34,7 @@
* @serial exclude
*/
class RegularEnumSet> extends EnumSet {
+ private static final long serialVersionUID = 3411599620347842686L;
/**
* Bit vector representation of this set. The 2^k bit indicates the
* presence of universe[k] in this set.
@@ -106,7 +107,7 @@
public void remove() {
if (lastReturned == 0)
throw new IllegalStateException();
- elements -= lastReturned;
+ elements &= ~lastReturned;
lastReturned = 0;
}
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/TreeMap.java
--- a/jdk/src/share/classes/java/util/TreeMap.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/TreeMap.java Wed Jul 05 17:39:17 2017 +0200
@@ -528,11 +528,8 @@
public V put(K key, V value) {
Entry t = root;
if (t == null) {
- // TBD:
- // 5045147: (coll) Adding null to an empty TreeSet should
- // throw NullPointerException
- //
- // compare(key, key); // type check
+ compare(key, key); // type (and possibly null) check
+
root = new Entry<>(key, value, null);
size = 1;
modCount++;
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/UUID.java
--- a/jdk/src/share/classes/java/util/UUID.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/UUID.java Wed Jul 05 17:39:17 2017 +0200
@@ -26,8 +26,6 @@
package java.util;
import java.security.*;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
/**
* A class that represents an immutable universally unique identifier (UUID).
@@ -91,36 +89,6 @@
private final long leastSigBits;
/*
- * The version number associated with this UUID. Computed on demand.
- */
- private transient int version = -1;
-
- /*
- * The variant number associated with this UUID. Computed on demand.
- */
- private transient int variant = -1;
-
- /*
- * The timestamp associated with this UUID. Computed on demand.
- */
- private transient volatile long timestamp = -1;
-
- /*
- * The clock sequence associated with this UUID. Computed on demand.
- */
- private transient int sequence = -1;
-
- /*
- * The node number associated with this UUID. Computed on demand.
- */
- private transient long node = -1;
-
- /*
- * The hashcode of this UUID. Computed on demand.
- */
- private transient int hashCode = -1;
-
- /*
* The random number generator used by this class to create random
* based UUIDs.
*/
@@ -134,7 +102,7 @@
private UUID(byte[] data) {
long msb = 0;
long lsb = 0;
- assert data.length == 16;
+ assert data.length == 16 : "data must be 16 bytes in length";
for (int i=0; i<8; i++)
msb = (msb << 8) | (data[i] & 0xff);
for (int i=8; i<16; i++)
@@ -276,11 +244,8 @@
* @return The version number of this {@code UUID}
*/
public int version() {
- if (version < 0) {
- // Version is bits masked by 0x000000000000F000 in MS long
- version = (int)((mostSigBits >> 12) & 0x0f);
- }
- return version;
+ // Version is bits masked by 0x000000000000F000 in MS long
+ return (int)((mostSigBits >> 12) & 0x0f);
}
/**
@@ -298,17 +263,13 @@
* @return The variant number of this {@code UUID}
*/
public int variant() {
- if (variant < 0) {
- // This field is composed of a varying number of bits
- if ((leastSigBits >>> 63) == 0) {
- variant = 0;
- } else if ((leastSigBits >>> 62) == 2) {
- variant = 2;
- } else {
- variant = (int)(leastSigBits >>> 61);
- }
- }
- return variant;
+ // This field is composed of a varying number of bits.
+ // 0 - - Reserved for NCS backward compatibility
+ // 1 0 - The Leach-Salz variant (used by this class)
+ // 1 1 0 Reserved, Microsoft backward compatibility
+ // 1 1 1 Reserved for future definition.
+ return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62)))
+ & (leastSigBits >> 63));
}
/**
@@ -330,14 +291,10 @@
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
- long result = timestamp;
- if (result < 0) {
- result = (mostSigBits & 0x0000000000000FFFL) << 48;
- result |= ((mostSigBits >> 16) & 0xFFFFL) << 32;
- result |= mostSigBits >>> 32;
- timestamp = result;
- }
- return result;
+
+ return (mostSigBits & 0x0FFFL) << 48
+ | ((mostSigBits >> 16) & 0x0FFFFL) << 32
+ | mostSigBits >>> 32;
}
/**
@@ -360,10 +317,8 @@
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
- if (sequence < 0) {
- sequence = (int)((leastSigBits & 0x3FFF000000000000L) >>> 48);
- }
- return sequence;
+
+ return (int)((leastSigBits & 0x3FFF000000000000L) >>> 48);
}
/**
@@ -386,10 +341,8 @@
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
- if (node < 0) {
- node = leastSigBits & 0x0000FFFFFFFFFFFFL;
- }
- return node;
+
+ return leastSigBits & 0x0000FFFFFFFFFFFFL;
}
// Object Inherited Methods
@@ -438,13 +391,8 @@
* @return A hash code value for this {@code UUID}
*/
public int hashCode() {
- if (hashCode == -1) {
- hashCode = (int)((mostSigBits >> 32) ^
- mostSigBits ^
- (leastSigBits >> 32) ^
- leastSigBits);
- }
- return hashCode;
+ long hilo = mostSigBits ^ leastSigBits;
+ return ((int)(hilo >> 32)) ^ (int) hilo;
}
/**
@@ -460,9 +408,7 @@
* otherwise
*/
public boolean equals(Object obj) {
- if (!(obj instanceof UUID))
- return false;
- if (((UUID)obj).variant() != this.variant())
+ if ((null == obj) || (obj.getClass() != UUID.class))
return false;
UUID id = (UUID)obj;
return (mostSigBits == id.mostSigBits &&
@@ -494,23 +440,4 @@
(this.leastSigBits > val.leastSigBits ? 1 :
0))));
}
-
- /**
- * Reconstitute the {@code UUID} instance from a stream (that is,
- * deserialize it). This is necessary to set the transient fields to their
- * correct uninitialized value so they will be recomputed on demand.
- */
- private void readObject(java.io.ObjectInputStream in)
- throws java.io.IOException, ClassNotFoundException {
-
- in.defaultReadObject();
-
- // Set "cached computation" fields to their initial values
- version = -1;
- variant = -1;
- timestamp = -1;
- sequence = -1;
- node = -1;
- hashCode = -1;
- }
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Wed Jul 05 17:39:17 2017 +0200
@@ -44,8 +44,8 @@
* creation time, depending on which constructor is used.
*
* This class implements a concurrent variant of SkipLists providing
- * expected average log(n) time cost for the
+ * href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists
+ * providing expected average log(n) time cost for the
* containsKey , get , put and
* remove operations and their variants. Insertion, removal,
* update, and access operations safely execute concurrently by
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/concurrent/Exchanger.java
--- a/jdk/src/share/classes/java/util/concurrent/Exchanger.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Exchanger.java Wed Jul 05 17:39:17 2017 +0200
@@ -164,8 +164,8 @@
* races between two threads or thread pre-emptions occurring
* between reading and CASing. Also, very transient peak
* contention can be much higher than the average sustainable
- * levels. The max limit is decreased on average 50% of the times
- * that a non-slot-zero wait elapses without being fulfilled.
+ * levels. An attempt to decrease the max limit is usually made
+ * when a non-slot-zero wait elapses without being fulfilled.
* Threads experiencing elapsed waits move closer to zero, so
* eventually find existing (or future) threads even if the table
* has been shrunk due to inactivity. The chosen mechanics and
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Wed Jul 05 17:39:17 2017 +0200
@@ -40,6 +40,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Random;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
@@ -51,6 +52,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.Condition;
/**
* An {@link ExecutorService} for running {@link ForkJoinTask}s.
@@ -158,239 +160,208 @@
* set of worker threads: Submissions from non-FJ threads enter
* into a submission queue. Workers take these tasks and typically
* split them into subtasks that may be stolen by other workers.
- * The main work-stealing mechanics implemented in class
- * ForkJoinWorkerThread give first priority to processing tasks
- * from their own queues (LIFO or FIFO, depending on mode), then
- * to randomized FIFO steals of tasks in other worker queues, and
- * lastly to new submissions. These mechanics do not consider
- * affinities, loads, cache localities, etc, so rarely provide the
- * best possible performance on a given machine, but portably
- * provide good throughput by averaging over these factors.
- * (Further, even if we did try to use such information, we do not
- * usually have a basis for exploiting it. For example, some sets
- * of tasks profit from cache affinities, but others are harmed by
- * cache pollution effects.)
+ * Preference rules give first priority to processing tasks from
+ * their own queues (LIFO or FIFO, depending on mode), then to
+ * randomized FIFO steals of tasks in other worker queues, and
+ * lastly to new submissions.
+ *
+ * The main throughput advantages of work-stealing stem from
+ * decentralized control -- workers mostly take tasks from
+ * themselves or each other. We cannot negate this in the
+ * implementation of other management responsibilities. The main
+ * tactic for avoiding bottlenecks is packing nearly all
+ * essentially atomic control state into a single 64bit volatile
+ * variable ("ctl"). This variable is read on the order of 10-100
+ * times as often as it is modified (always via CAS). (There is
+ * some additional control state, for example variable "shutdown"
+ * for which we can cope with uncoordinated updates.) This
+ * streamlines synchronization and control at the expense of messy
+ * constructions needed to repack status bits upon updates.
+ * Updates tend not to contend with each other except during
+ * bursts while submitted tasks begin or end. In some cases when
+ * they do contend, threads can instead do something else
+ * (usually, scan for tasks) until contention subsides.
+ *
+ * To enable packing, we restrict maximum parallelism to (1<<15)-1
+ * (which is far in excess of normal operating range) to allow
+ * ids, counts, and their negations (used for thresholding) to fit
+ * into 16bit fields.
+ *
+ * Recording Workers. Workers are recorded in the "workers" array
+ * that is created upon pool construction and expanded if (rarely)
+ * necessary. This is an array as opposed to some other data
+ * structure to support index-based random steals by workers.
+ * Updates to the array recording new workers and unrecording
+ * terminated ones are protected from each other by a seqLock
+ * (scanGuard) but the array is otherwise concurrently readable,
+ * and accessed directly by workers. To simplify index-based
+ * operations, the array size is always a power of two, and all
+ * readers must tolerate null slots. To avoid flailing during
+ * start-up, the array is presized to hold twice #parallelism
+ * workers (which is unlikely to need further resizing during
+ * execution). But to avoid dealing with so many null slots,
+ * variable scanGuard includes a mask for the nearest power of two
+ * that contains all current workers. All worker thread creation
+ * is on-demand, triggered by task submissions, replacement of
+ * terminated workers, and/or compensation for blocked
+ * workers. However, all other support code is set up to work with
+ * other policies. To ensure that we do not hold on to worker
+ * references that would prevent GC, ALL accesses to workers are
+ * via indices into the workers array (which is one source of some
+ * of the messy code constructions here). In essence, the workers
+ * array serves as a weak reference mechanism. Thus for example
+ * the wait queue field of ctl stores worker indices, not worker
+ * references. Access to the workers in associated methods (for
+ * example signalWork) must both index-check and null-check the
+ * IDs. All such accesses ignore bad IDs by returning out early
+ * from what they are doing, since this can only be associated
+ * with termination, in which case it is OK to give up.
*
- * Beyond work-stealing support and essential bookkeeping, the
- * main responsibility of this framework is to take actions when
- * one worker is waiting to join a task stolen (or always held by)
- * another. Because we are multiplexing many tasks on to a pool
- * of workers, we can't just let them block (as in Thread.join).
- * We also cannot just reassign the joiner's run-time stack with
- * another and replace it later, which would be a form of
- * "continuation", that even if possible is not necessarily a good
- * idea. Given that the creation costs of most threads on most
- * systems mainly surrounds setting up runtime stacks, thread
- * creation and switching is usually not much more expensive than
- * stack creation and switching, and is more flexible). Instead we
+ * All uses of the workers array, as well as queue arrays, check
+ * that the array is non-null (even if previously non-null). This
+ * allows nulling during termination, which is currently not
+ * necessary, but remains an option for resource-revocation-based
+ * shutdown schemes.
+ *
+ * Wait Queuing. Unlike HPC work-stealing frameworks, we cannot
+ * let workers spin indefinitely scanning for tasks when none can
+ * be found immediately, and we cannot start/resume workers unless
+ * there appear to be tasks available. On the other hand, we must
+ * quickly prod them into action when new tasks are submitted or
+ * generated. We park/unpark workers after placing in an event
+ * wait queue when they cannot find work. This "queue" is actually
+ * a simple Treiber stack, headed by the "id" field of ctl, plus a
+ * 15bit counter value to both wake up waiters (by advancing their
+ * count) and avoid ABA effects. Successors are held in worker
+ * field "nextWait". Queuing deals with several intrinsic races,
+ * mainly that a task-producing thread can miss seeing (and
+ * signalling) another thread that gave up looking for work but
+ * has not yet entered the wait queue. We solve this by requiring
+ * a full sweep of all workers both before (in scan()) and after
+ * (in tryAwaitWork()) a newly waiting worker is added to the wait
+ * queue. During a rescan, the worker might release some other
+ * queued worker rather than itself, which has the same net
+ * effect. Because enqueued workers may actually be rescanning
+ * rather than waiting, we set and clear the "parked" field of
+ * ForkJoinWorkerThread to reduce unnecessary calls to unpark.
+ * (Use of the parked field requires a secondary recheck to avoid
+ * missed signals.)
+ *
+ * Signalling. We create or wake up workers only when there
+ * appears to be at least one task they might be able to find and
+ * execute. When a submission is added or another worker adds a
+ * task to a queue that previously had two or fewer tasks, they
+ * signal waiting workers (or trigger creation of new ones if
+ * fewer than the given parallelism level -- see signalWork).
+ * These primary signals are buttressed by signals during rescans
+ * as well as those performed when a worker steals a task and
+ * notices that there are more tasks too; together these cover the
+ * signals needed in cases when more than two tasks are pushed
+ * but untaken.
+ *
+ * Trimming workers. To release resources after periods of lack of
+ * use, a worker starting to wait when the pool is quiescent will
+ * time out and terminate if the pool has remained quiescent for
+ * SHRINK_RATE nanosecs. This will slowly propagate, eventually
+ * terminating all workers after long periods of non-use.
+ *
+ * Submissions. External submissions are maintained in an
+ * array-based queue that is structured identically to
+ * ForkJoinWorkerThread queues except for the use of
+ * submissionLock in method addSubmission. Unlike the case for
+ * worker queues, multiple external threads can add new
+ * submissions, so adding requires a lock.
+ *
+ * Compensation. Beyond work-stealing support and lifecycle
+ * control, the main responsibility of this framework is to take
+ * actions when one worker is waiting to join a task stolen (or
+ * always held by) another. Because we are multiplexing many
+ * tasks on to a pool of workers, we can't just let them block (as
+ * in Thread.join). We also cannot just reassign the joiner's
+ * run-time stack with another and replace it later, which would
+ * be a form of "continuation", that even if possible is not
+ * necessarily a good idea since we sometimes need both an
+ * unblocked task and its continuation to progress. Instead we
* combine two tactics:
*
* Helping: Arranging for the joiner to execute some task that it
* would be running if the steal had not occurred. Method
- * ForkJoinWorkerThread.helpJoinTask tracks joining->stealing
+ * ForkJoinWorkerThread.joinTask tracks joining->stealing
* links to try to find such a task.
*
* Compensating: Unless there are already enough live threads,
- * method helpMaintainParallelism() may create or
- * re-activate a spare thread to compensate for blocked
- * joiners until they unblock.
- *
- * It is impossible to keep exactly the target (parallelism)
- * number of threads running at any given time. Determining
- * existence of conservatively safe helping targets, the
- * availability of already-created spares, and the apparent need
- * to create new spares are all racy and require heuristic
- * guidance, so we rely on multiple retries of each. Compensation
- * occurs in slow-motion. It is triggered only upon timeouts of
- * Object.wait used for joins. This reduces poor decisions that
- * would otherwise be made when threads are waiting for others
- * that are stalled because of unrelated activities such as
- * garbage collection.
+ * method tryPreBlock() may create or re-activate a spare
+ * thread to compensate for blocked joiners until they
+ * unblock.
*
* The ManagedBlocker extension API can't use helping so relies
* only on compensation in method awaitBlocker.
*
- * The main throughput advantages of work-stealing stem from
- * decentralized control -- workers mostly steal tasks from each
- * other. We do not want to negate this by creating bottlenecks
- * implementing other management responsibilities. So we use a
- * collection of techniques that avoid, reduce, or cope well with
- * contention. These entail several instances of bit-packing into
- * CASable fields to maintain only the minimally required
- * atomicity. To enable such packing, we restrict maximum
- * parallelism to (1<<15)-1 (enabling twice this (to accommodate
- * unbalanced increments and decrements) to fit into a 16 bit
- * field, which is far in excess of normal operating range. Even
- * though updates to some of these bookkeeping fields do sometimes
- * contend with each other, they don't normally cache-contend with
- * updates to others enough to warrant memory padding or
- * isolation. So they are all held as fields of ForkJoinPool
- * objects. The main capabilities are as follows:
- *
- * 1. Creating and removing workers. Workers are recorded in the
- * "workers" array. This is an array as opposed to some other data
- * structure to support index-based random steals by workers.
- * Updates to the array recording new workers and unrecording
- * terminated ones are protected from each other by a lock
- * (workerLock) but the array is otherwise concurrently readable,
- * and accessed directly by workers. To simplify index-based
- * operations, the array size is always a power of two, and all
- * readers must tolerate null slots. Currently, all worker thread
- * creation is on-demand, triggered by task submissions,
- * replacement of terminated workers, and/or compensation for
- * blocked workers. However, all other support code is set up to
- * work with other policies.
- *
- * To ensure that we do not hold on to worker references that
- * would prevent GC, ALL accesses to workers are via indices into
- * the workers array (which is one source of some of the unusual
- * code constructions here). In essence, the workers array serves
- * as a WeakReference mechanism. Thus for example the event queue
- * stores worker indices, not worker references. Access to the
- * workers in associated methods (for example releaseEventWaiters)
- * must both index-check and null-check the IDs. All such accesses
- * ignore bad IDs by returning out early from what they are doing,
- * since this can only be associated with shutdown, in which case
- * it is OK to give up. On termination, we just clobber these
- * data structures without trying to use them.
- *
- * 2. Bookkeeping for dynamically adding and removing workers. We
- * aim to approximately maintain the given level of parallelism.
- * When some workers are known to be blocked (on joins or via
- * ManagedBlocker), we may create or resume others to take their
- * place until they unblock (see below). Implementing this
- * requires counts of the number of "running" threads (i.e., those
- * that are neither blocked nor artificially suspended) as well as
- * the total number. These two values are packed into one field,
- * "workerCounts" because we need accurate snapshots when deciding
- * to create, resume or suspend. Note however that the
- * correspondence of these counts to reality is not guaranteed. In
- * particular updates for unblocked threads may lag until they
- * actually wake up.
- *
- * 3. Maintaining global run state. The run state of the pool
- * consists of a runLevel (SHUTDOWN, TERMINATING, etc) similar to
- * those in other Executor implementations, as well as a count of
- * "active" workers -- those that are, or soon will be, or
- * recently were executing tasks. The runLevel and active count
- * are packed together in order to correctly trigger shutdown and
- * termination. Without care, active counts can be subject to very
- * high contention. We substantially reduce this contention by
- * relaxing update rules. A worker must claim active status
- * prospectively, by activating if it sees that a submitted or
- * stealable task exists (it may find after activating that the
- * task no longer exists). It stays active while processing this
- * task (if it exists) and any other local subtasks it produces,
- * until it cannot find any other tasks. It then tries
- * inactivating (see method preStep), but upon update contention
- * instead scans for more tasks, later retrying inactivation if it
- * doesn't find any.
+ * It is impossible to keep exactly the target parallelism number
+ * of threads running at any given time. Determining the
+ * existence of conservatively safe helping targets, the
+ * availability of already-created spares, and the apparent need
+ * to create new spares are all racy and require heuristic
+ * guidance, so we rely on multiple retries of each. Currently,
+ * in keeping with on-demand signalling policy, we compensate only
+ * if blocking would leave less than one active (non-waiting,
+ * non-blocked) worker. Additionally, to avoid some false alarms
+ * due to GC, lagging counters, system activity, etc, compensated
+ * blocking for joins is only attempted after rechecks stabilize
+ * (retries are interspersed with Thread.yield, for good
+ * citizenship). The variable blockedCount, incremented before
+ * blocking and decremented after, is sometimes needed to
+ * distinguish cases of waiting for work vs blocking on joins or
+ * other managed sync. Both cases are equivalent for most pool
+ * control, so we can update non-atomically. (Additionally,
+ * contention on blockedCount alleviates some contention on ctl).
*
- * 4. Managing idle workers waiting for tasks. We cannot let
- * workers spin indefinitely scanning for tasks when none are
- * available. On the other hand, we must quickly prod them into
- * action when new tasks are submitted or generated. We
- * park/unpark these idle workers using an event-count scheme.
- * Field eventCount is incremented upon events that may enable
- * workers that previously could not find a task to now find one:
- * Submission of a new task to the pool, or another worker pushing
- * a task onto a previously empty queue. (We also use this
- * mechanism for configuration and termination actions that
- * require wakeups of idle workers). Each worker maintains its
- * last known event count, and blocks when a scan for work did not
- * find a task AND its lastEventCount matches the current
- * eventCount. Waiting idle workers are recorded in a variant of
- * Treiber stack headed by field eventWaiters which, when nonzero,
- * encodes the thread index and count awaited for by the worker
- * thread most recently calling eventSync. This thread in turn has
- * a record (field nextEventWaiter) for the next waiting worker.
- * In addition to allowing simpler decisions about need for
- * wakeup, the event count bits in eventWaiters serve the role of
- * tags to avoid ABA errors in Treiber stacks. Upon any wakeup,
- * released threads also try to release at most two others. The
- * net effect is a tree-like diffusion of signals, where released
- * threads (and possibly others) help with unparks. To further
- * reduce contention effects a bit, failed CASes to increment
- * field eventCount are tolerated without retries in signalWork.
- * Conceptually they are merged into the same event, which is OK
- * when their only purpose is to enable workers to scan for work.
+ * Shutdown and Termination. A call to shutdownNow atomically sets
+ * the ctl stop bit and then (non-atomically) sets each workers
+ * "terminate" status, cancels all unprocessed tasks, and wakes up
+ * all waiting workers. Detecting whether termination should
+ * commence after a non-abrupt shutdown() call requires more work
+ * and bookkeeping. We need consensus about quiesence (i.e., that
+ * there is no more work) which is reflected in active counts so
+ * long as there are no current blockers, as well as possible
+ * re-evaluations during independent changes in blocking or
+ * quiescing workers.
*
- * 5. Managing suspension of extra workers. When a worker notices
- * (usually upon timeout of a wait()) that there are too few
- * running threads, we may create a new thread to maintain
- * parallelism level, or at least avoid starvation. Usually, extra
- * threads are needed for only very short periods, yet join
- * dependencies are such that we sometimes need them in
- * bursts. Rather than create new threads each time this happens,
- * we suspend no-longer-needed extra ones as "spares". For most
- * purposes, we don't distinguish "extra" spare threads from
- * normal "core" threads: On each call to preStep (the only point
- * at which we can do this) a worker checks to see if there are
- * now too many running workers, and if so, suspends itself.
- * Method helpMaintainParallelism looks for suspended threads to
- * resume before considering creating a new replacement. The
- * spares themselves are encoded on another variant of a Treiber
- * Stack, headed at field "spareWaiters". Note that the use of
- * spares is intrinsically racy. One thread may become a spare at
- * about the same time as another is needlessly being created. We
- * counteract this and related slop in part by requiring resumed
- * spares to immediately recheck (in preStep) to see whether they
- * should re-suspend.
- *
- * 6. Killing off unneeded workers. A timeout mechanism is used to
- * shed unused workers: The oldest (first) event queue waiter uses
- * a timed rather than hard wait. When this wait times out without
- * a normal wakeup, it tries to shutdown any one (for convenience
- * the newest) other spare or event waiter via
- * tryShutdownUnusedWorker. This eventually reduces the number of
- * worker threads to a minimum of one after a long enough period
- * without use.
- *
- * 7. Deciding when to create new workers. The main dynamic
- * control in this class is deciding when to create extra threads
- * in method helpMaintainParallelism. We would like to keep
- * exactly #parallelism threads running, which is an impossible
- * task. We always need to create one when the number of running
- * threads would become zero and all workers are busy. Beyond
- * this, we must rely on heuristics that work well in the
- * presence of transient phenomena such as GC stalls, dynamic
- * compilation, and wake-up lags. These transients are extremely
- * common -- we are normally trying to fully saturate the CPUs on
- * a machine, so almost any activity other than running tasks
- * impedes accuracy. Our main defense is to allow parallelism to
- * lapse for a while during joins, and use a timeout to see if,
- * after the resulting settling, there is still a need for
- * additional workers. This also better copes with the fact that
- * some of the methods in this class tend to never become compiled
- * (but are interpreted), so some components of the entire set of
- * controls might execute 100 times faster than others. And
- * similarly for cases where the apparent lack of work is just due
- * to GC stalls and other transient system activity.
- *
- * Beware that there is a lot of representation-level coupling
+ * Style notes: There is a lot of representation-level coupling
* among classes ForkJoinPool, ForkJoinWorkerThread, and
- * ForkJoinTask. For example, direct access to "workers" array by
+ * ForkJoinTask. Most fields of ForkJoinWorkerThread maintain
+ * data structures managed by ForkJoinPool, so are directly
+ * accessed. Conversely we allow access to "workers" array by
* workers, and direct access to ForkJoinTask.status by both
* ForkJoinPool and ForkJoinWorkerThread. There is little point
* trying to reduce this, since any associated future changes in
* representations will need to be accompanied by algorithmic
- * changes anyway.
+ * changes anyway. All together, these low-level implementation
+ * choices produce as much as a factor of 4 performance
+ * improvement compared to naive implementations, and enable the
+ * processing of billions of tasks per second, at the expense of
+ * some ugliness.
*
- * Style notes: There are lots of inline assignments (of form
- * "while ((local = field) != 0)") which are usually the simplest
- * way to ensure the required read orderings (which are sometimes
- * critical). Also several occurrences of the unusual "do {}
- * while (!cas...)" which is the simplest way to force an update of
- * a CAS'ed variable. There are also other coding oddities that
- * help some methods perform reasonably even when interpreted (not
- * compiled), at the expense of some messy constructions that
- * reduce byte code counts.
+ * Methods signalWork() and scan() are the main bottlenecks so are
+ * especially heavily micro-optimized/mangled. There are lots of
+ * inline assignments (of form "while ((local = field) != 0)")
+ * which are usually the simplest way to ensure the required read
+ * orderings (which are sometimes critical). This leads to a
+ * "C"-like style of listing declarations of these locals at the
+ * heads of methods or blocks. There are several occurrences of
+ * the unusual "do {} while (!cas...)" which is the simplest way
+ * to force an update of a CAS'ed variable. There are also other
+ * coding oddities that help some methods perform reasonably even
+ * when interpreted (not compiled).
*
- * The order of declarations in this file is: (1) statics (2)
- * fields (along with constants used when unpacking some of them)
- * (3) internal control methods (4) callbacks and other support
- * for ForkJoinTask and ForkJoinWorkerThread classes, (5) exported
- * methods (plus a few little helpers).
+ * The order of declarations in this file is: (1) declarations of
+ * statics (2) fields (along with constants used when unpacking
+ * some of them), listed in an order that tends to reduce
+ * contention among them a bit under most JVMs. (3) internal
+ * control methods (4) callbacks and other support for
+ * ForkJoinTask and ForkJoinWorkerThread classes, (5) exported
+ * methods (plus a few little helpers). (6) static block
+ * initializing all statics in a minimally dependent order.
*/
/**
@@ -425,15 +396,13 @@
* overridden in ForkJoinPool constructors.
*/
public static final ForkJoinWorkerThreadFactory
- defaultForkJoinWorkerThreadFactory =
- new DefaultForkJoinWorkerThreadFactory();
+ defaultForkJoinWorkerThreadFactory;
/**
* Permission required for callers of methods that may start or
* kill threads.
*/
- private static final RuntimePermission modifyThreadPermission =
- new RuntimePermission("modifyThread");
+ private static final RuntimePermission modifyThreadPermission;
/**
* If there is a security manager, makes sure caller has
@@ -448,63 +417,59 @@
/**
* Generator for assigning sequence numbers as pool names.
*/
- private static final AtomicInteger poolNumberGenerator =
- new AtomicInteger();
+ private static final AtomicInteger poolNumberGenerator;
/**
- * The time to block in a join (see awaitJoin) before checking if
- * a new worker should be (re)started to maintain parallelism
- * level. The value should be short enough to maintain global
- * responsiveness and progress but long enough to avoid
- * counterproductive firings during GC stalls or unrelated system
- * activity, and to not bog down systems with continual re-firings
- * on GCs or legitimately long waits.
+ * Generator for initial random seeds for worker victim
+ * selection. This is used only to create initial seeds. Random
+ * steals use a cheaper xorshift generator per steal attempt. We
+ * don't expect much contention on seedGenerator, so just use a
+ * plain Random.
*/
- private static final long JOIN_TIMEOUT_MILLIS = 250L; // 4 per second
+ static final Random workerSeedGenerator;
/**
- * The wakeup interval (in nanoseconds) for the oldest worker
- * waiting for an event to invoke tryShutdownUnusedWorker to
- * shrink the number of workers. The exact value does not matter
- * too much. It must be short enough to release resources during
- * sustained periods of idleness, but not so short that threads
- * are continually re-created.
+ * Array holding all worker threads in the pool. Initialized upon
+ * construction. Array size must be a power of two. Updates and
+ * replacements are protected by scanGuard, but the array is
+ * always kept in a consistent enough state to be randomly
+ * accessed without locking by workers performing work-stealing,
+ * as well as other traversal-based methods in this class, so long
+ * as reads memory-acquire by first reading ctl. All readers must
+ * tolerate that some array slots may be null.
*/
- private static final long SHRINK_RATE_NANOS =
- 30L * 1000L * 1000L * 1000L; // 2 per minute
+ ForkJoinWorkerThread[] workers;
/**
- * Absolute bound for parallelism level. Twice this number plus
- * one (i.e., 0xfff) must fit into a 16bit field to enable
- * word-packing for some counts and indices.
+ * Initial size for submission queue array. Must be a power of
+ * two. In many applications, these always stay small so we use a
+ * small initial cap.
*/
- private static final int MAX_WORKERS = 0x7fff;
+ private static final int INITIAL_QUEUE_CAPACITY = 8;
+
+ /**
+ * Maximum size for submission queue array. Must be a power of two
+ * less than or equal to 1 << (31 - width of array entry) to
+ * ensure lack of index wraparound, but is capped at a lower
+ * value to help users trap runaway computations.
+ */
+ private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M
/**
- * Array holding all worker threads in the pool. Array size must
- * be a power of two. Updates and replacements are protected by
- * workerLock, but the array is always kept in a consistent enough
- * state to be randomly accessed without locking by workers
- * performing work-stealing, as well as other traversal-based
- * methods in this class. All readers must tolerate that some
- * array slots may be null.
+ * Array serving as submission queue. Initialized upon construction.
*/
- volatile ForkJoinWorkerThread[] workers;
+ private ForkJoinTask>[] submissionQueue;
/**
- * Queue for external submissions.
+ * Lock protecting submissions array for addSubmission
*/
- private final LinkedTransferQueue> submissionQueue;
+ private final ReentrantLock submissionLock;
/**
- * Lock protecting updates to workers array.
+ * Condition for awaitTermination, using submissionLock for
+ * convenience.
*/
- private final ReentrantLock workerLock;
-
- /**
- * Latch released upon termination.
- */
- private final Phaser termination;
+ private final Condition termination;
/**
* Creation factory for worker threads.
@@ -512,227 +477,719 @@
private final ForkJoinWorkerThreadFactory factory;
/**
+ * The uncaught exception handler used when any worker abruptly
+ * terminates.
+ */
+ final Thread.UncaughtExceptionHandler ueh;
+
+ /**
+ * Prefix for assigning names to worker threads
+ */
+ private final String workerNamePrefix;
+
+ /**
* Sum of per-thread steal counts, updated only when threads are
* idle or terminating.
*/
private volatile long stealCount;
/**
- * Encoded record of top of Treiber stack of threads waiting for
- * events. The top 32 bits contain the count being waited for. The
- * bottom 16 bits contains one plus the pool index of waiting
- * worker thread. (Bits 16-31 are unused.)
+ * Main pool control -- a long packed with:
+ * AC: Number of active running workers minus target parallelism (16 bits)
+ * TC: Number of total workers minus target parallelism (16bits)
+ * ST: true if pool is terminating (1 bit)
+ * EC: the wait count of top waiting thread (15 bits)
+ * ID: ~poolIndex of top of Treiber stack of waiting threads (16 bits)
+ *
+ * When convenient, we can extract the upper 32 bits of counts and
+ * the lower 32 bits of queue state, u = (int)(ctl >>> 32) and e =
+ * (int)ctl. The ec field is never accessed alone, but always
+ * together with id and st. The offsets of counts by the target
+ * parallelism and the positionings of fields makes it possible to
+ * perform the most common checks via sign tests of fields: When
+ * ac is negative, there are not enough active workers, when tc is
+ * negative, there are not enough total workers, when id is
+ * negative, there is at least one waiting worker, and when e is
+ * negative, the pool is terminating. To deal with these possibly
+ * negative fields, we use casts in and out of "short" and/or
+ * signed shifts to maintain signedness.
*/
- private volatile long eventWaiters;
-
- private static final int EVENT_COUNT_SHIFT = 32;
- private static final int WAITER_ID_MASK = (1 << 16) - 1;
-
- /**
- * A counter for events that may wake up worker threads:
- * - Submission of a new task to the pool
- * - A worker pushing a task on an empty queue
- * - termination
- */
- private volatile int eventCount;
-
- /**
- * Encoded record of top of Treiber stack of spare threads waiting
- * for resumption. The top 16 bits contain an arbitrary count to
- * avoid ABA effects. The bottom 16bits contains one plus the pool
- * index of waiting worker thread.
- */
- private volatile int spareWaiters;
-
- private static final int SPARE_COUNT_SHIFT = 16;
- private static final int SPARE_ID_MASK = (1 << 16) - 1;
+ volatile long ctl;
- /**
- * Lifecycle control. The low word contains the number of workers
- * that are (probably) executing tasks. This value is atomically
- * incremented before a worker gets a task to run, and decremented
- * when a worker has no tasks and cannot find any. Bits 16-18
- * contain runLevel value. When all are zero, the pool is
- * running. Level transitions are monotonic (running -> shutdown
- * -> terminating -> terminated) so each transition adds a bit.
- * These are bundled together to ensure consistent read for
- * termination checks (i.e., that runLevel is at least SHUTDOWN
- * and active threads is zero).
- *
- * Notes: Most direct CASes are dependent on these bitfield
- * positions. Also, this field is non-private to enable direct
- * performance-sensitive CASes in ForkJoinWorkerThread.
- */
- volatile int runState;
+ // bit positions/shifts for fields
+ private static final int AC_SHIFT = 48;
+ private static final int TC_SHIFT = 32;
+ private static final int ST_SHIFT = 31;
+ private static final int EC_SHIFT = 16;
+
+ // bounds
+ private static final int MAX_ID = 0x7fff; // max poolIndex
+ private static final int SMASK = 0xffff; // mask short bits
+ private static final int SHORT_SIGN = 1 << 15;
+ private static final int INT_SIGN = 1 << 31;
- // Note: The order among run level values matters.
- private static final int RUNLEVEL_SHIFT = 16;
- private static final int SHUTDOWN = 1 << RUNLEVEL_SHIFT;
- private static final int TERMINATING = 1 << (RUNLEVEL_SHIFT + 1);
- private static final int TERMINATED = 1 << (RUNLEVEL_SHIFT + 2);
- private static final int ACTIVE_COUNT_MASK = (1 << RUNLEVEL_SHIFT) - 1;
+ // masks
+ private static final long STOP_BIT = 0x0001L << ST_SHIFT;
+ private static final long AC_MASK = ((long)SMASK) << AC_SHIFT;
+ private static final long TC_MASK = ((long)SMASK) << TC_SHIFT;
+
+ // units for incrementing and decrementing
+ private static final long TC_UNIT = 1L << TC_SHIFT;
+ private static final long AC_UNIT = 1L << AC_SHIFT;
- /**
- * Holds number of total (i.e., created and not yet terminated)
- * and running (i.e., not blocked on joins or other managed sync)
- * threads, packed together to ensure consistent snapshot when
- * making decisions about creating and suspending spare
- * threads. Updated only by CAS. Note that adding a new worker
- * requires incrementing both counts, since workers start off in
- * running state.
- */
- private volatile int workerCounts;
+ // masks and units for dealing with u = (int)(ctl >>> 32)
+ private static final int UAC_SHIFT = AC_SHIFT - 32;
+ private static final int UTC_SHIFT = TC_SHIFT - 32;
+ private static final int UAC_MASK = SMASK << UAC_SHIFT;
+ private static final int UTC_MASK = SMASK << UTC_SHIFT;
+ private static final int UAC_UNIT = 1 << UAC_SHIFT;
+ private static final int UTC_UNIT = 1 << UTC_SHIFT;
- private static final int TOTAL_COUNT_SHIFT = 16;
- private static final int RUNNING_COUNT_MASK = (1 << TOTAL_COUNT_SHIFT) - 1;
- private static final int ONE_RUNNING = 1;
- private static final int ONE_TOTAL = 1 << TOTAL_COUNT_SHIFT;
+ // masks and units for dealing with e = (int)ctl
+ private static final int E_MASK = 0x7fffffff; // no STOP_BIT
+ private static final int EC_UNIT = 1 << EC_SHIFT;
/**
* The target parallelism level.
- * Accessed directly by ForkJoinWorkerThreads.
*/
final int parallelism;
/**
+ * Index (mod submission queue length) of next element to take
+ * from submission queue. Usage is identical to that for
+ * per-worker queues -- see ForkJoinWorkerThread internal
+ * documentation.
+ */
+ volatile int queueBase;
+
+ /**
+ * Index (mod submission queue length) of next element to add
+ * in submission queue. Usage is identical to that for
+ * per-worker queues -- see ForkJoinWorkerThread internal
+ * documentation.
+ */
+ int queueTop;
+
+ /**
+ * True when shutdown() has been called.
+ */
+ volatile boolean shutdown;
+
+ /**
* True if use local fifo, not default lifo, for local polling
* Read by, and replicated by ForkJoinWorkerThreads
*/
final boolean locallyFifo;
/**
- * The uncaught exception handler used when any worker abruptly
- * terminates.
+ * The number of threads in ForkJoinWorkerThreads.helpQuiescePool.
+ * When non-zero, suppresses automatic shutdown when active
+ * counts become zero.
+ */
+ volatile int quiescerCount;
+
+ /**
+ * The number of threads blocked in join.
+ */
+ volatile int blockedCount;
+
+ /**
+ * Counter for worker Thread names (unrelated to their poolIndex)
+ */
+ private volatile int nextWorkerNumber;
+
+ /**
+ * The index for the next created worker. Accessed under scanGuard.
*/
- private final Thread.UncaughtExceptionHandler ueh;
+ private int nextWorkerIndex;
+
+ /**
+ * SeqLock and index masking for updates to workers array. Locked
+ * when SG_UNIT is set. Unlocking clears bit by adding
+ * SG_UNIT. Staleness of read-only operations can be checked by
+ * comparing scanGuard to value before the reads. The low 16 bits
+ * (i.e, anding with SMASK) hold (the smallest power of two
+ * covering all worker indices, minus one, and is used to avoid
+ * dealing with large numbers of null slots when the workers array
+ * is overallocated.
+ */
+ volatile int scanGuard;
+
+ private static final int SG_UNIT = 1 << 16;
+
+ /**
+ * The wakeup interval (in nanoseconds) for a worker waiting for a
+ * task when the pool is quiescent to instead try to shrink the
+ * number of workers. The exact value does not matter too
+ * much. It must be short enough to release resources during
+ * sustained periods of idleness, but not so short that threads
+ * are continually re-created.
+ */
+ private static final long SHRINK_RATE =
+ 4L * 1000L * 1000L * 1000L; // 4 seconds
/**
- * Pool number, just for assigning useful names to worker threads
+ * Top-level loop for worker threads: On each step: if the
+ * previous step swept through all queues and found no tasks, or
+ * there are excess threads, then possibly blocks. Otherwise,
+ * scans for and, if found, executes a task. Returns when pool
+ * and/or worker terminate.
+ *
+ * @param w the worker
*/
- private final int poolNumber;
+ final void work(ForkJoinWorkerThread w) {
+ boolean swept = false; // true on empty scans
+ long c;
+ while (!w.terminate && (int)(c = ctl) >= 0) {
+ int a; // active count
+ if (!swept && (a = (int)(c >> AC_SHIFT)) <= 0)
+ swept = scan(w, a);
+ else if (tryAwaitWork(w, c))
+ swept = false;
+ }
+ }
- // Utilities for CASing fields. Note that most of these
- // are usually manually inlined by callers
+ // Signalling
/**
- * Increments running count part of workerCounts.
+ * Wakes up or creates a worker.
*/
- final void incrementRunningCount() {
- int c;
- do {} while (!UNSAFE.compareAndSwapInt(this, workerCountsOffset,
- c = workerCounts,
- c + ONE_RUNNING));
+ final void signalWork() {
+ /*
+ * The while condition is true if: (there is are too few total
+ * workers OR there is at least one waiter) AND (there are too
+ * few active workers OR the pool is terminating). The value
+ * of e distinguishes the remaining cases: zero (no waiters)
+ * for create, negative if terminating (in which case do
+ * nothing), else release a waiter. The secondary checks for
+ * release (non-null array etc) can fail if the pool begins
+ * terminating after the test, and don't impose any added cost
+ * because JVMs must perform null and bounds checks anyway.
+ */
+ long c; int e, u;
+ while ((((e = (int)(c = ctl)) | (u = (int)(c >>> 32))) &
+ (INT_SIGN|SHORT_SIGN)) == (INT_SIGN|SHORT_SIGN) && e >= 0) {
+ if (e > 0) { // release a waiting worker
+ int i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws;
+ if ((ws = workers) == null ||
+ (i = ~e & SMASK) >= ws.length ||
+ (w = ws[i]) == null)
+ break;
+ long nc = (((long)(w.nextWait & E_MASK)) |
+ ((long)(u + UAC_UNIT) << 32));
+ if (w.eventCount == e &&
+ UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
+ w.eventCount = (e + EC_UNIT) & E_MASK;
+ if (w.parked)
+ UNSAFE.unpark(w);
+ break;
+ }
+ }
+ else if (UNSAFE.compareAndSwapLong
+ (this, ctlOffset, c,
+ (long)(((u + UTC_UNIT) & UTC_MASK) |
+ ((u + UAC_UNIT) & UAC_MASK)) << 32)) {
+ addWorker();
+ break;
+ }
+ }
}
/**
- * Tries to increment running count part of workerCounts.
+ * Variant of signalWork to help release waiters on rescans.
+ * Tries once to release a waiter if active count < 0.
+ *
+ * @return false if failed due to contention, else true
+ */
+ private boolean tryReleaseWaiter() {
+ long c; int e, i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws;
+ if ((e = (int)(c = ctl)) > 0 &&
+ (int)(c >> AC_SHIFT) < 0 &&
+ (ws = workers) != null &&
+ (i = ~e & SMASK) < ws.length &&
+ (w = ws[i]) != null) {
+ long nc = ((long)(w.nextWait & E_MASK) |
+ ((c + AC_UNIT) & (AC_MASK|TC_MASK)));
+ if (w.eventCount != e ||
+ !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc))
+ return false;
+ w.eventCount = (e + EC_UNIT) & E_MASK;
+ if (w.parked)
+ UNSAFE.unpark(w);
+ }
+ return true;
+ }
+
+ // Scanning for tasks
+
+ /**
+ * Scans for and, if found, executes one task. Scans start at a
+ * random index of workers array, and randomly select the first
+ * (2*#workers)-1 probes, and then, if all empty, resort to 2
+ * circular sweeps, which is necessary to check quiescence. and
+ * taking a submission only if no stealable tasks were found. The
+ * steal code inside the loop is a specialized form of
+ * ForkJoinWorkerThread.deqTask, followed bookkeeping to support
+ * helpJoinTask and signal propagation. The code for submission
+ * queues is almost identical. On each steal, the worker completes
+ * not only the task, but also all local tasks that this task may
+ * have generated. On detecting staleness or contention when
+ * trying to take a task, this method returns without finishing
+ * sweep, which allows global state rechecks before retry.
+ *
+ * @param w the worker
+ * @param a the number of active workers
+ * @return true if swept all queues without finding a task
*/
- final boolean tryIncrementRunningCount() {
- int c;
- return UNSAFE.compareAndSwapInt(this, workerCountsOffset,
- c = workerCounts,
- c + ONE_RUNNING);
+ private boolean scan(ForkJoinWorkerThread w, int a) {
+ int g = scanGuard; // mask 0 avoids useless scans if only one active
+ int m = (parallelism == 1 - a && blockedCount == 0) ? 0 : g & SMASK;
+ ForkJoinWorkerThread[] ws = workers;
+ if (ws == null || ws.length <= m) // staleness check
+ return false;
+ for (int r = w.seed, k = r, j = -(m + m); j <= m + m; ++j) {
+ ForkJoinTask> t; ForkJoinTask>[] q; int b, i;
+ ForkJoinWorkerThread v = ws[k & m];
+ if (v != null && (b = v.queueBase) != v.queueTop &&
+ (q = v.queue) != null && (i = (q.length - 1) & b) >= 0) {
+ long u = (i << ASHIFT) + ABASE;
+ if ((t = q[i]) != null && v.queueBase == b &&
+ UNSAFE.compareAndSwapObject(q, u, t, null)) {
+ int d = (v.queueBase = b + 1) - v.queueTop;
+ v.stealHint = w.poolIndex;
+ if (d != 0)
+ signalWork(); // propagate if nonempty
+ w.execTask(t);
+ }
+ r ^= r << 13; r ^= r >>> 17; w.seed = r ^ (r << 5);
+ return false; // store next seed
+ }
+ else if (j < 0) { // xorshift
+ r ^= r << 13; r ^= r >>> 17; k = r ^= r << 5;
+ }
+ else
+ ++k;
+ }
+ if (scanGuard != g) // staleness check
+ return false;
+ else { // try to take submission
+ ForkJoinTask> t; ForkJoinTask>[] q; int b, i;
+ if ((b = queueBase) != queueTop &&
+ (q = submissionQueue) != null &&
+ (i = (q.length - 1) & b) >= 0) {
+ long u = (i << ASHIFT) + ABASE;
+ if ((t = q[i]) != null && queueBase == b &&
+ UNSAFE.compareAndSwapObject(q, u, t, null)) {
+ queueBase = b + 1;
+ w.execTask(t);
+ }
+ return false;
+ }
+ return true; // all queues empty
+ }
}
/**
- * Tries to decrement running count unless already zero.
- */
- final boolean tryDecrementRunningCount() {
- int wc = workerCounts;
- if ((wc & RUNNING_COUNT_MASK) == 0)
- return false;
- return UNSAFE.compareAndSwapInt(this, workerCountsOffset,
- wc, wc - ONE_RUNNING);
- }
-
- /**
- * Forces decrement of encoded workerCounts, awaiting nonzero if
- * (rarely) necessary when other count updates lag.
+ * Tries to enqueue worker w in wait queue and await change in
+ * worker's eventCount. If the pool is quiescent, possibly
+ * terminates worker upon exit. Otherwise, before blocking,
+ * rescans queues to avoid missed signals. Upon finding work,
+ * releases at least one worker (which may be the current
+ * worker). Rescans restart upon detected staleness or failure to
+ * release due to contention. Note the unusual conventions about
+ * Thread.interrupt here and elsewhere: Because interrupts are
+ * used solely to alert threads to check termination, which is
+ * checked here anyway, we clear status (using Thread.interrupted)
+ * before any call to park, so that park does not immediately
+ * return due to status being set via some other unrelated call to
+ * interrupt in user code.
*
- * @param dr -- either zero or ONE_RUNNING
- * @param dt -- either zero or ONE_TOTAL
+ * @param w the calling worker
+ * @param c the ctl value on entry
+ * @return true if waited or another thread was released upon enq
*/
- private void decrementWorkerCounts(int dr, int dt) {
- for (;;) {
- int wc = workerCounts;
- if ((wc & RUNNING_COUNT_MASK) - dr < 0 ||
- (wc >>> TOTAL_COUNT_SHIFT) - dt < 0) {
- if ((runState & TERMINATED) != 0)
- return; // lagging termination on a backout
- Thread.yield();
+ private boolean tryAwaitWork(ForkJoinWorkerThread w, long c) {
+ int v = w.eventCount;
+ w.nextWait = (int)c; // w's successor record
+ long nc = (long)(v & E_MASK) | ((c - AC_UNIT) & (AC_MASK|TC_MASK));
+ if (ctl != c || !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
+ long d = ctl; // return true if lost to a deq, to force scan
+ return (int)d != (int)c && ((d - c) & AC_MASK) >= 0L;
+ }
+ for (int sc = w.stealCount; sc != 0;) { // accumulate stealCount
+ long s = stealCount;
+ if (UNSAFE.compareAndSwapLong(this, stealCountOffset, s, s + sc))
+ sc = w.stealCount = 0;
+ else if (w.eventCount != v)
+ return true; // update next time
+ }
+ if (parallelism + (int)(nc >> AC_SHIFT) == 0 &&
+ blockedCount == 0 && quiescerCount == 0)
+ idleAwaitWork(w, nc, c, v); // quiescent
+ for (boolean rescanned = false;;) {
+ if (w.eventCount != v)
+ return true;
+ if (!rescanned) {
+ int g = scanGuard, m = g & SMASK;
+ ForkJoinWorkerThread[] ws = workers;
+ if (ws != null && m < ws.length) {
+ rescanned = true;
+ for (int i = 0; i <= m; ++i) {
+ ForkJoinWorkerThread u = ws[i];
+ if (u != null) {
+ if (u.queueBase != u.queueTop &&
+ !tryReleaseWaiter())
+ rescanned = false; // contended
+ if (w.eventCount != v)
+ return true;
+ }
+ }
+ }
+ if (scanGuard != g || // stale
+ (queueBase != queueTop && !tryReleaseWaiter()))
+ rescanned = false;
+ if (!rescanned)
+ Thread.yield(); // reduce contention
+ else
+ Thread.interrupted(); // clear before park
}
- if (UNSAFE.compareAndSwapInt(this, workerCountsOffset,
- wc, wc - (dr + dt)))
- return;
+ else {
+ w.parked = true; // must recheck
+ if (w.eventCount != v) {
+ w.parked = false;
+ return true;
+ }
+ LockSupport.park(this);
+ rescanned = w.parked = false;
+ }
}
}
/**
- * Tries decrementing active count; fails on contention.
- * Called when workers cannot find tasks to run.
+ * If inactivating worker w has caused pool to become
+ * quiescent, check for pool termination, and wait for event
+ * for up to SHRINK_RATE nanosecs (rescans are unnecessary in
+ * this case because quiescence reflects consensus about lack
+ * of work). On timeout, if ctl has not changed, terminate the
+ * worker. Upon its termination (see deregisterWorker), it may
+ * wake up another worker to possibly repeat this process.
+ *
+ * @param w the calling worker
+ * @param currentCtl the ctl value after enqueuing w
+ * @param prevCtl the ctl value if w terminated
+ * @param v the eventCount w awaits change
*/
- final boolean tryDecrementActiveCount() {
- int c;
- return UNSAFE.compareAndSwapInt(this, runStateOffset,
- c = runState, c - 1);
+ private void idleAwaitWork(ForkJoinWorkerThread w, long currentCtl,
+ long prevCtl, int v) {
+ if (w.eventCount == v) {
+ if (shutdown)
+ tryTerminate(false);
+ ForkJoinTask.helpExpungeStaleExceptions(); // help clean weak refs
+ while (ctl == currentCtl) {
+ long startTime = System.nanoTime();
+ w.parked = true;
+ if (w.eventCount == v) // must recheck
+ LockSupport.parkNanos(this, SHRINK_RATE);
+ w.parked = false;
+ if (w.eventCount != v)
+ break;
+ else if (System.nanoTime() - startTime < SHRINK_RATE)
+ Thread.interrupted(); // spurious wakeup
+ else if (UNSAFE.compareAndSwapLong(this, ctlOffset,
+ currentCtl, prevCtl)) {
+ w.terminate = true; // restore previous
+ w.eventCount = ((int)currentCtl + EC_UNIT) & E_MASK;
+ break;
+ }
+ }
+ }
}
+ // Submissions
+
/**
- * Advances to at least the given level. Returns true if not
- * already in at least the given level.
+ * Enqueues the given task in the submissionQueue. Same idea as
+ * ForkJoinWorkerThread.pushTask except for use of submissionLock.
+ *
+ * @param t the task
*/
- private boolean advanceRunLevel(int level) {
- for (;;) {
- int s = runState;
- if ((s & level) != 0)
- return false;
- if (UNSAFE.compareAndSwapInt(this, runStateOffset, s, s | level))
- return true;
+ private void addSubmission(ForkJoinTask> t) {
+ final ReentrantLock lock = this.submissionLock;
+ lock.lock();
+ try {
+ ForkJoinTask>[] q; int s, m;
+ if ((q = submissionQueue) != null) { // ignore if queue removed
+ long u = (((s = queueTop) & (m = q.length-1)) << ASHIFT)+ABASE;
+ UNSAFE.putOrderedObject(q, u, t);
+ queueTop = s + 1;
+ if (s - queueBase == m)
+ growSubmissionQueue();
+ }
+ } finally {
+ lock.unlock();
+ }
+ signalWork();
+ }
+
+ // (pollSubmission is defined below with exported methods)
+
+ /**
+ * Creates or doubles submissionQueue array.
+ * Basically identical to ForkJoinWorkerThread version.
+ */
+ private void growSubmissionQueue() {
+ ForkJoinTask>[] oldQ = submissionQueue;
+ int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY;
+ if (size > MAXIMUM_QUEUE_CAPACITY)
+ throw new RejectedExecutionException("Queue capacity exceeded");
+ if (size < INITIAL_QUEUE_CAPACITY)
+ size = INITIAL_QUEUE_CAPACITY;
+ ForkJoinTask>[] q = submissionQueue = new ForkJoinTask>[size];
+ int mask = size - 1;
+ int top = queueTop;
+ int oldMask;
+ if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) {
+ for (int b = queueBase; b != top; ++b) {
+ long u = ((b & oldMask) << ASHIFT) + ABASE;
+ Object x = UNSAFE.getObjectVolatile(oldQ, u);
+ if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null))
+ UNSAFE.putObjectVolatile
+ (q, ((b & mask) << ASHIFT) + ABASE, x);
+ }
}
}
- // workers array maintenance
+ // Blocking support
/**
- * Records and returns a workers array index for new worker.
+ * Tries to increment blockedCount, decrement active count
+ * (sometimes implicitly) and possibly release or create a
+ * compensating worker in preparation for blocking. Fails
+ * on contention or termination.
+ *
+ * @return true if the caller can block, else should recheck and retry
*/
- private int recordWorker(ForkJoinWorkerThread w) {
- // Try using slot totalCount-1. If not available, scan and/or resize
- int k = (workerCounts >>> TOTAL_COUNT_SHIFT) - 1;
- final ReentrantLock lock = this.workerLock;
- lock.lock();
- try {
- ForkJoinWorkerThread[] ws = workers;
- int n = ws.length;
- if (k < 0 || k >= n || ws[k] != null) {
- for (k = 0; k < n && ws[k] != null; ++k)
- ;
- if (k == n)
- ws = workers = Arrays.copyOf(ws, n << 1);
+ private boolean tryPreBlock() {
+ int b = blockedCount;
+ if (UNSAFE.compareAndSwapInt(this, blockedCountOffset, b, b + 1)) {
+ int pc = parallelism;
+ do {
+ ForkJoinWorkerThread[] ws; ForkJoinWorkerThread w;
+ int e, ac, tc, rc, i;
+ long c = ctl;
+ int u = (int)(c >>> 32);
+ if ((e = (int)c) < 0) {
+ // skip -- terminating
+ }
+ else if ((ac = (u >> UAC_SHIFT)) <= 0 && e != 0 &&
+ (ws = workers) != null &&
+ (i = ~e & SMASK) < ws.length &&
+ (w = ws[i]) != null) {
+ long nc = ((long)(w.nextWait & E_MASK) |
+ (c & (AC_MASK|TC_MASK)));
+ if (w.eventCount == e &&
+ UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
+ w.eventCount = (e + EC_UNIT) & E_MASK;
+ if (w.parked)
+ UNSAFE.unpark(w);
+ return true; // release an idle worker
+ }
+ }
+ else if ((tc = (short)(u >>> UTC_SHIFT)) >= 0 && ac + pc > 1) {
+ long nc = ((c - AC_UNIT) & AC_MASK) | (c & ~AC_MASK);
+ if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc))
+ return true; // no compensation needed
+ }
+ else if (tc + pc < MAX_ID) {
+ long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK);
+ if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
+ addWorker();
+ return true; // create a replacement
+ }
+ }
+ // try to back out on any failure and let caller retry
+ } while (!UNSAFE.compareAndSwapInt(this, blockedCountOffset,
+ b = blockedCount, b - 1));
+ }
+ return false;
+ }
+
+ /**
+ * Decrements blockedCount and increments active count
+ */
+ private void postBlock() {
+ long c;
+ do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, // no mask
+ c = ctl, c + AC_UNIT));
+ int b;
+ do {} while(!UNSAFE.compareAndSwapInt(this, blockedCountOffset,
+ b = blockedCount, b - 1));
+ }
+
+ /**
+ * Possibly blocks waiting for the given task to complete, or
+ * cancels the task if terminating. Fails to wait if contended.
+ *
+ * @param joinMe the task
+ */
+ final void tryAwaitJoin(ForkJoinTask> joinMe) {
+ int s;
+ Thread.interrupted(); // clear interrupts before checking termination
+ if (joinMe.status >= 0) {
+ if (tryPreBlock()) {
+ joinMe.tryAwaitDone(0L);
+ postBlock();
}
- ws[k] = w;
- int c = eventCount; // advance event count to ensure visibility
- UNSAFE.compareAndSwapInt(this, eventCountOffset, c, c+1);
- } finally {
- lock.unlock();
+ else if ((ctl & STOP_BIT) != 0L)
+ joinMe.cancelIgnoringExceptions();
}
- return k;
}
/**
- * Nulls out record of worker in workers array.
+ * Possibly blocks the given worker waiting for joinMe to
+ * complete or timeout
+ *
+ * @param joinMe the task
+ * @param millis the wait time for underlying Object.wait
+ */
+ final void timedAwaitJoin(ForkJoinTask> joinMe, long nanos) {
+ while (joinMe.status >= 0) {
+ Thread.interrupted();
+ if ((ctl & STOP_BIT) != 0L) {
+ joinMe.cancelIgnoringExceptions();
+ break;
+ }
+ if (tryPreBlock()) {
+ long last = System.nanoTime();
+ while (joinMe.status >= 0) {
+ long millis = TimeUnit.NANOSECONDS.toMillis(nanos);
+ if (millis <= 0)
+ break;
+ joinMe.tryAwaitDone(millis);
+ if (joinMe.status < 0)
+ break;
+ if ((ctl & STOP_BIT) != 0L) {
+ joinMe.cancelIgnoringExceptions();
+ break;
+ }
+ long now = System.nanoTime();
+ nanos -= now - last;
+ last = now;
+ }
+ postBlock();
+ break;
+ }
+ }
+ }
+
+ /**
+ * If necessary, compensates for blocker, and blocks
+ */
+ private void awaitBlocker(ManagedBlocker blocker)
+ throws InterruptedException {
+ while (!blocker.isReleasable()) {
+ if (tryPreBlock()) {
+ try {
+ do {} while (!blocker.isReleasable() && !blocker.block());
+ } finally {
+ postBlock();
+ }
+ break;
+ }
+ }
+ }
+
+ // Creating, registering and deregistring workers
+
+ /**
+ * Tries to create and start a worker; minimally rolls back counts
+ * on failure.
*/
- private void forgetWorker(ForkJoinWorkerThread w) {
- int idx = w.poolIndex;
- // Locking helps method recordWorker avoid unnecessary expansion
- final ReentrantLock lock = this.workerLock;
- lock.lock();
+ private void addWorker() {
+ Throwable ex = null;
+ ForkJoinWorkerThread t = null;
try {
- ForkJoinWorkerThread[] ws = workers;
- if (idx >= 0 && idx < ws.length && ws[idx] == w) // verify
- ws[idx] = null;
- } finally {
- lock.unlock();
+ t = factory.newThread(this);
+ } catch (Throwable e) {
+ ex = e;
+ }
+ if (t == null) { // null or exceptional factory return
+ long c; // adjust counts
+ do {} while (!UNSAFE.compareAndSwapLong
+ (this, ctlOffset, c = ctl,
+ (((c - AC_UNIT) & AC_MASK) |
+ ((c - TC_UNIT) & TC_MASK) |
+ (c & ~(AC_MASK|TC_MASK)))));
+ // Propagate exception if originating from an external caller
+ if (!tryTerminate(false) && ex != null &&
+ !(Thread.currentThread() instanceof ForkJoinWorkerThread))
+ UNSAFE.throwException(ex);
+ }
+ else
+ t.start();
+ }
+
+ /**
+ * Callback from ForkJoinWorkerThread constructor to assign a
+ * public name
+ */
+ final String nextWorkerName() {
+ for (int n;;) {
+ if (UNSAFE.compareAndSwapInt(this, nextWorkerNumberOffset,
+ n = nextWorkerNumber, ++n))
+ return workerNamePrefix + n;
+ }
+ }
+
+ /**
+ * Callback from ForkJoinWorkerThread constructor to
+ * determine its poolIndex and record in workers array.
+ *
+ * @param w the worker
+ * @return the worker's pool index
+ */
+ final int registerWorker(ForkJoinWorkerThread w) {
+ /*
+ * In the typical case, a new worker acquires the lock, uses
+ * next available index and returns quickly. Since we should
+ * not block callers (ultimately from signalWork or
+ * tryPreBlock) waiting for the lock needed to do this, we
+ * instead help release other workers while waiting for the
+ * lock.
+ */
+ for (int g;;) {
+ ForkJoinWorkerThread[] ws;
+ if (((g = scanGuard) & SG_UNIT) == 0 &&
+ UNSAFE.compareAndSwapInt(this, scanGuardOffset,
+ g, g | SG_UNIT)) {
+ int k = nextWorkerIndex;
+ try {
+ if ((ws = workers) != null) { // ignore on shutdown
+ int n = ws.length;
+ if (k < 0 || k >= n || ws[k] != null) {
+ for (k = 0; k < n && ws[k] != null; ++k)
+ ;
+ if (k == n)
+ ws = workers = Arrays.copyOf(ws, n << 1);
+ }
+ ws[k] = w;
+ nextWorkerIndex = k + 1;
+ int m = g & SMASK;
+ g = k >= m? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1);
+ }
+ } finally {
+ scanGuard = g;
+ }
+ return k;
+ }
+ else if ((ws = workers) != null) { // help release others
+ for (ForkJoinWorkerThread u : ws) {
+ if (u != null && u.queueBase != u.queueTop) {
+ if (tryReleaseWaiter())
+ break;
+ }
+ }
+ }
}
}
@@ -743,415 +1200,46 @@
*
* @param w the worker
*/
- final void workerTerminated(ForkJoinWorkerThread w) {
- forgetWorker(w);
- decrementWorkerCounts(w.isTrimmed() ? 0 : ONE_RUNNING, ONE_TOTAL);
- while (w.stealCount != 0) // collect final count
- tryAccumulateStealCount(w);
- tryTerminate(false);
- }
-
- // Waiting for and signalling events
-
- /**
- * Releases workers blocked on a count not equal to current count.
- * Normally called after precheck that eventWaiters isn't zero to
- * avoid wasted array checks. Gives up upon a change in count or
- * upon releasing four workers, letting others take over.
- */
- private void releaseEventWaiters() {
- ForkJoinWorkerThread[] ws = workers;
- int n = ws.length;
- long h = eventWaiters;
- int ec = eventCount;
- int releases = 4;
- ForkJoinWorkerThread w; int id;
- while ((id = (((int)h) & WAITER_ID_MASK) - 1) >= 0 &&
- (int)(h >>> EVENT_COUNT_SHIFT) != ec &&
- id < n && (w = ws[id]) != null) {
- if (UNSAFE.compareAndSwapLong(this, eventWaitersOffset,
- h, w.nextWaiter)) {
- LockSupport.unpark(w);
- if (--releases == 0)
- break;
- }
- if (eventCount != ec)
- break;
- h = eventWaiters;
- }
- }
-
- /**
- * Tries to advance eventCount and releases waiters. Called only
- * from workers.
- */
- final void signalWork() {
- int c; // try to increment event count -- CAS failure OK
- UNSAFE.compareAndSwapInt(this, eventCountOffset, c = eventCount, c+1);
- if (eventWaiters != 0L)
- releaseEventWaiters();
- }
-
- /**
- * Adds the given worker to event queue and blocks until
- * terminating or event count advances from the given value
- *
- * @param w the calling worker thread
- * @param ec the count
- */
- private void eventSync(ForkJoinWorkerThread w, int ec) {
- long nh = (((long)ec) << EVENT_COUNT_SHIFT) | ((long)(w.poolIndex+1));
- long h;
- while ((runState < SHUTDOWN || !tryTerminate(false)) &&
- (((int)(h = eventWaiters) & WAITER_ID_MASK) == 0 ||
- (int)(h >>> EVENT_COUNT_SHIFT) == ec) &&
- eventCount == ec) {
- if (UNSAFE.compareAndSwapLong(this, eventWaitersOffset,
- w.nextWaiter = h, nh)) {
- awaitEvent(w, ec);
- break;
+ final void deregisterWorker(ForkJoinWorkerThread w, Throwable ex) {
+ int idx = w.poolIndex;
+ int sc = w.stealCount;
+ int steps = 0;
+ // Remove from array, adjust worker counts and collect steal count.
+ // We can intermix failed removes or adjusts with steal updates
+ do {
+ long s, c;
+ int g;
+ if (steps == 0 && ((g = scanGuard) & SG_UNIT) == 0 &&
+ UNSAFE.compareAndSwapInt(this, scanGuardOffset,
+ g, g |= SG_UNIT)) {
+ ForkJoinWorkerThread[] ws = workers;
+ if (ws != null && idx >= 0 &&
+ idx < ws.length && ws[idx] == w)
+ ws[idx] = null; // verify
+ nextWorkerIndex = idx;
+ scanGuard = g + SG_UNIT;
+ steps = 1;
}
- }
- }
-
- /**
- * Blocks the given worker (that has already been entered as an
- * event waiter) until terminating or event count advances from
- * the given value. The oldest (first) waiter uses a timed wait to
- * occasionally one-by-one shrink the number of workers (to a
- * minimum of one) if the pool has not been used for extended
- * periods.
- *
- * @param w the calling worker thread
- * @param ec the count
- */
- private void awaitEvent(ForkJoinWorkerThread w, int ec) {
- while (eventCount == ec) {
- if (tryAccumulateStealCount(w)) { // transfer while idle
- boolean untimed = (w.nextWaiter != 0L ||
- (workerCounts & RUNNING_COUNT_MASK) <= 1);
- long startTime = untimed ? 0 : System.nanoTime();
- Thread.interrupted(); // clear/ignore interrupt
- if (w.isTerminating() || eventCount != ec)
- break; // recheck after clear
- if (untimed)
- LockSupport.park(w);
- else {
- LockSupport.parkNanos(w, SHRINK_RATE_NANOS);
- if (eventCount != ec || w.isTerminating())
- break;
- if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS)
- tryShutdownUnusedWorker(ec);
- }
- }
- }
- }
-
- // Maintaining parallelism
-
- /**
- * Pushes worker onto the spare stack.
- */
- final void pushSpare(ForkJoinWorkerThread w) {
- int ns = (++w.spareCount << SPARE_COUNT_SHIFT) | (w.poolIndex + 1);
- do {} while (!UNSAFE.compareAndSwapInt(this, spareWaitersOffset,
- w.nextSpare = spareWaiters,ns));
- }
-
- /**
- * Tries (once) to resume a spare if the number of running
- * threads is less than target.
- */
- private void tryResumeSpare() {
- int sw, id;
- ForkJoinWorkerThread[] ws = workers;
- int n = ws.length;
- ForkJoinWorkerThread w;
- if ((sw = spareWaiters) != 0 &&
- (id = (sw & SPARE_ID_MASK) - 1) >= 0 &&
- id < n && (w = ws[id]) != null &&
- (runState >= TERMINATING ||
- (workerCounts & RUNNING_COUNT_MASK) < parallelism) &&
- spareWaiters == sw &&
- UNSAFE.compareAndSwapInt(this, spareWaitersOffset,
- sw, w.nextSpare)) {
- int c; // increment running count before resume
- do {} while (!UNSAFE.compareAndSwapInt
- (this, workerCountsOffset,
- c = workerCounts, c + ONE_RUNNING));
- if (w.tryUnsuspend())
- LockSupport.unpark(w);
- else // back out if w was shutdown
- decrementWorkerCounts(ONE_RUNNING, 0);
+ if (steps == 1 &&
+ UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl,
+ (((c - AC_UNIT) & AC_MASK) |
+ ((c - TC_UNIT) & TC_MASK) |
+ (c & ~(AC_MASK|TC_MASK)))))
+ steps = 2;
+ if (sc != 0 &&
+ UNSAFE.compareAndSwapLong(this, stealCountOffset,
+ s = stealCount, s + sc))
+ sc = 0;
+ } while (steps != 2 || sc != 0);
+ if (!tryTerminate(false)) {
+ if (ex != null) // possibly replace if died abnormally
+ signalWork();
+ else
+ tryReleaseWaiter();
}
}
- /**
- * Tries to increase the number of running workers if below target
- * parallelism: If a spare exists tries to resume it via
- * tryResumeSpare. Otherwise, if not enough total workers or all
- * existing workers are busy, adds a new worker. In all cases also
- * helps wake up releasable workers waiting for work.
- */
- private void helpMaintainParallelism() {
- int pc = parallelism;
- int wc, rs, tc;
- while (((wc = workerCounts) & RUNNING_COUNT_MASK) < pc &&
- (rs = runState) < TERMINATING) {
- if (spareWaiters != 0)
- tryResumeSpare();
- else if ((tc = wc >>> TOTAL_COUNT_SHIFT) >= MAX_WORKERS ||
- (tc >= pc && (rs & ACTIVE_COUNT_MASK) != tc))
- break; // enough total
- else if (runState == rs && workerCounts == wc &&
- UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc,
- wc + (ONE_RUNNING|ONE_TOTAL))) {
- ForkJoinWorkerThread w = null;
- Throwable fail = null;
- try {
- w = factory.newThread(this);
- } catch (Throwable ex) {
- fail = ex;
- }
- if (w == null) { // null or exceptional factory return
- decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
- tryTerminate(false); // handle failure during shutdown
- // If originating from an external caller,
- // propagate exception, else ignore
- if (fail != null && runState < TERMINATING &&
- !(Thread.currentThread() instanceof
- ForkJoinWorkerThread))
- UNSAFE.throwException(fail);
- break;
- }
- w.start(recordWorker(w), ueh);
- if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc)
- break; // add at most one unless total below target
- }
- }
- if (eventWaiters != 0L)
- releaseEventWaiters();
- }
-
- /**
- * Callback from the oldest waiter in awaitEvent waking up after a
- * period of non-use. If all workers are idle, tries (once) to
- * shutdown an event waiter or a spare, if one exists. Note that
- * we don't need CAS or locks here because the method is called
- * only from one thread occasionally waking (and even misfires are
- * OK). Note that until the shutdown worker fully terminates,
- * workerCounts will overestimate total count, which is tolerable.
- *
- * @param ec the event count waited on by caller (to abort
- * attempt if count has since changed).
- */
- private void tryShutdownUnusedWorker(int ec) {
- if (runState == 0 && eventCount == ec) { // only trigger if all idle
- ForkJoinWorkerThread[] ws = workers;
- int n = ws.length;
- ForkJoinWorkerThread w = null;
- boolean shutdown = false;
- int sw;
- long h;
- if ((sw = spareWaiters) != 0) { // prefer killing spares
- int id = (sw & SPARE_ID_MASK) - 1;
- if (id >= 0 && id < n && (w = ws[id]) != null &&
- UNSAFE.compareAndSwapInt(this, spareWaitersOffset,
- sw, w.nextSpare))
- shutdown = true;
- }
- else if ((h = eventWaiters) != 0L) {
- long nh;
- int id = (((int)h) & WAITER_ID_MASK) - 1;
- if (id >= 0 && id < n && (w = ws[id]) != null &&
- (nh = w.nextWaiter) != 0L && // keep at least one worker
- UNSAFE.compareAndSwapLong(this, eventWaitersOffset, h, nh))
- shutdown = true;
- }
- if (w != null && shutdown) {
- w.shutdown();
- LockSupport.unpark(w);
- }
- }
- releaseEventWaiters(); // in case of interference
- }
-
- /**
- * Callback from workers invoked upon each top-level action (i.e.,
- * stealing a task or taking a submission and running it).
- * Performs one or more of the following:
- *
- * 1. If the worker is active and either did not run a task
- * or there are too many workers, try to set its active status
- * to inactive and update activeCount. On contention, we may
- * try again in this or a subsequent call.
- *
- * 2. If not enough total workers, help create some.
- *
- * 3. If there are too many running workers, suspend this worker
- * (first forcing inactive if necessary). If it is not needed,
- * it may be shutdown while suspended (via
- * tryShutdownUnusedWorker). Otherwise, upon resume it
- * rechecks running thread count and need for event sync.
- *
- * 4. If worker did not run a task, await the next task event via
- * eventSync if necessary (first forcing inactivation), upon
- * which the worker may be shutdown via
- * tryShutdownUnusedWorker. Otherwise, help release any
- * existing event waiters that are now releasable,
- *
- * @param w the worker
- * @param ran true if worker ran a task since last call to this method
- */
- final void preStep(ForkJoinWorkerThread w, boolean ran) {
- int wec = w.lastEventCount;
- boolean active = w.active;
- boolean inactivate = false;
- int pc = parallelism;
- while (w.runState == 0) {
- int rs = runState;
- if (rs >= TERMINATING) { // propagate shutdown
- w.shutdown();
- break;
- }
- if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) &&
- UNSAFE.compareAndSwapInt(this, runStateOffset, rs, --rs)) {
- inactivate = active = w.active = false;
- if (rs == SHUTDOWN) { // all inactive and shut down
- tryTerminate(false);
- continue;
- }
- }
- int wc = workerCounts; // try to suspend as spare
- if ((wc & RUNNING_COUNT_MASK) > pc) {
- if (!(inactivate |= active) && // must inactivate to suspend
- workerCounts == wc &&
- UNSAFE.compareAndSwapInt(this, workerCountsOffset,
- wc, wc - ONE_RUNNING))
- w.suspendAsSpare();
- }
- else if ((wc >>> TOTAL_COUNT_SHIFT) < pc)
- helpMaintainParallelism(); // not enough workers
- else if (ran)
- break;
- else {
- long h = eventWaiters;
- int ec = eventCount;
- if (h != 0L && (int)(h >>> EVENT_COUNT_SHIFT) != ec)
- releaseEventWaiters(); // release others before waiting
- else if (ec != wec) {
- w.lastEventCount = ec; // no need to wait
- break;
- }
- else if (!(inactivate |= active))
- eventSync(w, wec); // must inactivate before sync
- }
- }
- }
-
- /**
- * Helps and/or blocks awaiting join of the given task.
- * See above for explanation.
- *
- * @param joinMe the task to join
- * @param worker the current worker thread
- * @param timed true if wait should time out
- * @param nanos timeout value if timed
- */
- final void awaitJoin(ForkJoinTask> joinMe, ForkJoinWorkerThread worker,
- boolean timed, long nanos) {
- long startTime = timed ? System.nanoTime() : 0L;
- int retries = 2 + (parallelism >> 2); // #helpJoins before blocking
- boolean running = true; // false when count decremented
- while (joinMe.status >= 0) {
- if (runState >= TERMINATING) {
- joinMe.cancelIgnoringExceptions();
- break;
- }
- running = worker.helpJoinTask(joinMe, running);
- if (joinMe.status < 0)
- break;
- if (retries > 0) {
- --retries;
- continue;
- }
- int wc = workerCounts;
- if ((wc & RUNNING_COUNT_MASK) != 0) {
- if (running) {
- if (!UNSAFE.compareAndSwapInt(this, workerCountsOffset,
- wc, wc - ONE_RUNNING))
- continue;
- running = false;
- }
- long h = eventWaiters;
- if (h != 0L && (int)(h >>> EVENT_COUNT_SHIFT) != eventCount)
- releaseEventWaiters();
- if ((workerCounts & RUNNING_COUNT_MASK) != 0) {
- long ms; int ns;
- if (!timed) {
- ms = JOIN_TIMEOUT_MILLIS;
- ns = 0;
- }
- else { // at most JOIN_TIMEOUT_MILLIS per wait
- long nt = nanos - (System.nanoTime() - startTime);
- if (nt <= 0L)
- break;
- ms = nt / 1000000;
- if (ms > JOIN_TIMEOUT_MILLIS) {
- ms = JOIN_TIMEOUT_MILLIS;
- ns = 0;
- }
- else
- ns = (int) (nt % 1000000);
- }
- joinMe.internalAwaitDone(ms, ns);
- }
- if (joinMe.status < 0)
- break;
- }
- helpMaintainParallelism();
- }
- if (!running) {
- int c;
- do {} while (!UNSAFE.compareAndSwapInt
- (this, workerCountsOffset,
- c = workerCounts, c + ONE_RUNNING));
- }
- }
-
- /**
- * Same idea as awaitJoin, but no helping, retries, or timeouts.
- */
- final void awaitBlocker(ManagedBlocker blocker)
- throws InterruptedException {
- while (!blocker.isReleasable()) {
- int wc = workerCounts;
- if ((wc & RUNNING_COUNT_MASK) == 0)
- helpMaintainParallelism();
- else if (UNSAFE.compareAndSwapInt(this, workerCountsOffset,
- wc, wc - ONE_RUNNING)) {
- try {
- while (!blocker.isReleasable()) {
- long h = eventWaiters;
- if (h != 0L &&
- (int)(h >>> EVENT_COUNT_SHIFT) != eventCount)
- releaseEventWaiters();
- else if ((workerCounts & RUNNING_COUNT_MASK) == 0 &&
- runState < TERMINATING)
- helpMaintainParallelism();
- else if (blocker.block())
- break;
- }
- } finally {
- int c;
- do {} while (!UNSAFE.compareAndSwapInt
- (this, workerCountsOffset,
- c = workerCounts, c + ONE_RUNNING));
- }
- break;
- }
- }
- }
+ // Shutdown and termination
/**
* Possibly initiates and/or completes termination.
@@ -1161,97 +1249,132 @@
* @return true if now terminating or terminated
*/
private boolean tryTerminate(boolean now) {
- if (now)
- advanceRunLevel(SHUTDOWN); // ensure at least SHUTDOWN
- else if (runState < SHUTDOWN ||
- !submissionQueue.isEmpty() ||
- (runState & ACTIVE_COUNT_MASK) != 0)
- return false;
-
- if (advanceRunLevel(TERMINATING))
- startTerminating();
-
- // Finish now if all threads terminated; else in some subsequent call
- if ((workerCounts >>> TOTAL_COUNT_SHIFT) == 0) {
- advanceRunLevel(TERMINATED);
- termination.forceTermination();
+ long c;
+ while (((c = ctl) & STOP_BIT) == 0) {
+ if (!now) {
+ if ((int)(c >> AC_SHIFT) != -parallelism)
+ return false;
+ if (!shutdown || blockedCount != 0 || quiescerCount != 0 ||
+ queueBase != queueTop) {
+ if (ctl == c) // staleness check
+ return false;
+ continue;
+ }
+ }
+ if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, c | STOP_BIT))
+ startTerminating();
+ }
+ if ((short)(c >>> TC_SHIFT) == -parallelism) { // signal when 0 workers
+ final ReentrantLock lock = this.submissionLock;
+ lock.lock();
+ try {
+ termination.signalAll();
+ } finally {
+ lock.unlock();
+ }
}
return true;
}
/**
- * Actions on transition to TERMINATING
- *
- * Runs up to four passes through workers: (0) shutting down each
- * (without waking up if parked) to quickly spread notifications
- * without unnecessary bouncing around event queues etc (1) wake
- * up and help cancel tasks (2) interrupt (3) mop up races with
- * interrupted workers
+ * Runs up to three passes through workers: (0) Setting
+ * termination status for each worker, followed by wakeups up to
+ * queued workers; (1) helping cancel tasks; (2) interrupting
+ * lagging threads (likely in external tasks, but possibly also
+ * blocked in joins). Each pass repeats previous steps because of
+ * potential lagging thread creation.
*/
private void startTerminating() {
cancelSubmissions();
- for (int passes = 0; passes < 4 && workerCounts != 0; ++passes) {
- int c; // advance event count
- UNSAFE.compareAndSwapInt(this, eventCountOffset,
- c = eventCount, c+1);
- eventWaiters = 0L; // clobber lists
- spareWaiters = 0;
- for (ForkJoinWorkerThread w : workers) {
- if (w != null) {
- w.shutdown();
- if (passes > 0 && !w.isTerminated()) {
- w.cancelTasks();
- LockSupport.unpark(w);
- if (passes > 1 && !w.isInterrupted()) {
- try {
- w.interrupt();
- } catch (SecurityException ignore) {
+ for (int pass = 0; pass < 3; ++pass) {
+ ForkJoinWorkerThread[] ws = workers;
+ if (ws != null) {
+ for (ForkJoinWorkerThread w : ws) {
+ if (w != null) {
+ w.terminate = true;
+ if (pass > 0) {
+ w.cancelTasks();
+ if (pass > 1 && !w.isInterrupted()) {
+ try {
+ w.interrupt();
+ } catch (SecurityException ignore) {
+ }
}
}
}
}
+ terminateWaiters();
+ }
+ }
+ }
+
+ /**
+ * Polls and cancels all submissions. Called only during termination.
+ */
+ private void cancelSubmissions() {
+ while (queueBase != queueTop) {
+ ForkJoinTask> task = pollSubmission();
+ if (task != null) {
+ try {
+ task.cancel(false);
+ } catch (Throwable ignore) {
+ }
}
}
}
/**
- * Clears out and cancels submissions, ignoring exceptions.
+ * Tries to set the termination status of waiting workers, and
+ * then wakes them up (after which they will terminate).
*/
- private void cancelSubmissions() {
- ForkJoinTask> task;
- while ((task = submissionQueue.poll()) != null) {
- try {
- task.cancel(false);
- } catch (Throwable ignore) {
+ private void terminateWaiters() {
+ ForkJoinWorkerThread[] ws = workers;
+ if (ws != null) {
+ ForkJoinWorkerThread w; long c; int i, e;
+ int n = ws.length;
+ while ((i = ~(e = (int)(c = ctl)) & SMASK) < n &&
+ (w = ws[i]) != null && w.eventCount == (e & E_MASK)) {
+ if (UNSAFE.compareAndSwapLong(this, ctlOffset, c,
+ (long)(w.nextWait & E_MASK) |
+ ((c + AC_UNIT) & AC_MASK) |
+ (c & (TC_MASK|STOP_BIT)))) {
+ w.terminate = true;
+ w.eventCount = e + EC_UNIT;
+ if (w.parked)
+ UNSAFE.unpark(w);
+ }
}
}
}
- // misc support for ForkJoinWorkerThread
+ // misc ForkJoinWorkerThread support
/**
- * Returns pool number.
+ * Increment or decrement quiescerCount. Needed only to prevent
+ * triggering shutdown if a worker is transiently inactive while
+ * checking quiescence.
+ *
+ * @param delta 1 for increment, -1 for decrement
*/
- final int getPoolNumber() {
- return poolNumber;
+ final void addQuiescerCount(int delta) {
+ int c;
+ do {} while(!UNSAFE.compareAndSwapInt(this, quiescerCountOffset,
+ c = quiescerCount, c + delta));
}
/**
- * Tries to accumulate steal count from a worker, clearing
- * the worker's value if successful.
+ * Directly increment or decrement active count without
+ * queuing. This method is used to transiently assert inactivation
+ * while checking quiescence.
*
- * @return true if worker steal count now zero
+ * @param delta 1 for increment, -1 for decrement
*/
- final boolean tryAccumulateStealCount(ForkJoinWorkerThread w) {
- int sc = w.stealCount;
- long c = stealCount;
- // CAS even if zero, for fence effects
- if (UNSAFE.compareAndSwapLong(this, stealCountOffset, c, c + sc)) {
- if (sc != 0)
- w.stealCount = 0;
- return true;
- }
- return sc == 0;
+ final void addActiveCount(int delta) {
+ long d = delta < 0 ? -AC_UNIT : AC_UNIT;
+ long c;
+ do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl,
+ ((c + d) & AC_MASK) |
+ (c & ~AC_MASK)));
}
/**
@@ -1259,16 +1382,17 @@
* active thread.
*/
final int idlePerActive() {
- int pc = parallelism; // use parallelism, not rc
- int ac = runState; // no mask -- artificially boosts during shutdown
- // Use exact results for small values, saturate past 4
- return ((pc <= ac) ? 0 :
- (pc >>> 1 <= ac) ? 1 :
- (pc >>> 2 <= ac) ? 3 :
- pc >>> 3);
+ // Approximate at powers of two for small values, saturate past 4
+ int p = parallelism;
+ int a = p + (int)(ctl >> AC_SHIFT);
+ return (a > (p >>>= 1) ? 0 :
+ a > (p >>>= 1) ? 1 :
+ a > (p >>>= 1) ? 2 :
+ a > (p >>>= 1) ? 4 :
+ 8);
}
- // Public and protected methods
+ // Exported methods
// Constructors
@@ -1337,49 +1461,42 @@
checkPermission();
if (factory == null)
throw new NullPointerException();
- if (parallelism <= 0 || parallelism > MAX_WORKERS)
+ if (parallelism <= 0 || parallelism > MAX_ID)
throw new IllegalArgumentException();
this.parallelism = parallelism;
this.factory = factory;
this.ueh = handler;
this.locallyFifo = asyncMode;
- int arraySize = initialArraySizeFor(parallelism);
- this.workers = new ForkJoinWorkerThread[arraySize];
- this.submissionQueue = new LinkedTransferQueue>();
- this.workerLock = new ReentrantLock();
- this.termination = new Phaser(1);
- this.poolNumber = poolNumberGenerator.incrementAndGet();
- }
-
- /**
- * Returns initial power of two size for workers array.
- * @param pc the initial parallelism level
- */
- private static int initialArraySizeFor(int pc) {
- // If possible, initially allocate enough space for one spare
- int size = pc < MAX_WORKERS ? pc + 1 : MAX_WORKERS;
- // See Hackers Delight, sec 3.2. We know MAX_WORKERS < (1 >>> 16)
- size |= size >>> 1;
- size |= size >>> 2;
- size |= size >>> 4;
- size |= size >>> 8;
- return size + 1;
+ long np = (long)(-parallelism); // offset ctl counts
+ this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
+ this.submissionQueue = new ForkJoinTask>[INITIAL_QUEUE_CAPACITY];
+ // initialize workers array with room for 2*parallelism if possible
+ int n = parallelism << 1;
+ if (n >= MAX_ID)
+ n = MAX_ID;
+ else { // See Hackers Delight, sec 3.2, where n < (1 << 16)
+ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8;
+ }
+ workers = new ForkJoinWorkerThread[n + 1];
+ this.submissionLock = new ReentrantLock();
+ this.termination = submissionLock.newCondition();
+ StringBuilder sb = new StringBuilder("ForkJoinPool-");
+ sb.append(poolNumberGenerator.incrementAndGet());
+ sb.append("-worker-");
+ this.workerNamePrefix = sb.toString();
}
// Execution methods
/**
- * Submits task and creates, starts, or resumes some workers if necessary
- */
- private void doSubmit(ForkJoinTask task) {
- submissionQueue.offer(task);
- int c; // try to increment event count -- CAS failure OK
- UNSAFE.compareAndSwapInt(this, eventCountOffset, c = eventCount, c+1);
- helpMaintainParallelism();
- }
-
- /**
* Performs the given task, returning its result upon completion.
+ * If the computation encounters an unchecked Exception or Error,
+ * it is rethrown as the outcome of this invocation. Rethrown
+ * exceptions behave in the same way as regular exceptions, but,
+ * when possible, contain stack traces (as displayed for example
+ * using {@code ex.printStackTrace()}) of both the current thread
+ * as well as the thread actually encountering the exception;
+ * minimally only the latter.
*
* @param task the task
* @return the task's result
@@ -1388,16 +1505,16 @@
* scheduled for execution
*/
public T invoke(ForkJoinTask task) {
+ Thread t = Thread.currentThread();
if (task == null)
throw new NullPointerException();
- if (runState >= SHUTDOWN)
+ if (shutdown)
throw new RejectedExecutionException();
- Thread t = Thread.currentThread();
if ((t instanceof ForkJoinWorkerThread) &&
((ForkJoinWorkerThread)t).pool == this)
return task.invoke(); // bypass submit if in same pool
else {
- doSubmit(task);
+ addSubmission(task);
return task.join();
}
}
@@ -1407,14 +1524,15 @@
* computation in the current pool, else submits as external task.
*/
private void forkOrSubmit(ForkJoinTask task) {
- if (runState >= SHUTDOWN)
+ ForkJoinWorkerThread w;
+ Thread t = Thread.currentThread();
+ if (shutdown)
throw new RejectedExecutionException();
- Thread t = Thread.currentThread();
if ((t instanceof ForkJoinWorkerThread) &&
- ((ForkJoinWorkerThread)t).pool == this)
- task.fork();
+ (w = (ForkJoinWorkerThread)t).pool == this)
+ w.pushTask(task);
else
- doSubmit(task);
+ addSubmission(task);
}
/**
@@ -1571,7 +1689,7 @@
* @return the number of worker threads
*/
public int getPoolSize() {
- return workerCounts >>> TOTAL_COUNT_SHIFT;
+ return parallelism + (short)(ctl >>> TC_SHIFT);
}
/**
@@ -1593,7 +1711,8 @@
* @return the number of worker threads
*/
public int getRunningThreadCount() {
- return workerCounts & RUNNING_COUNT_MASK;
+ int r = parallelism + (int)(ctl >> AC_SHIFT);
+ return r <= 0? 0 : r; // suppress momentarily negative values
}
/**
@@ -1604,7 +1723,8 @@
* @return the number of active threads
*/
public int getActiveThreadCount() {
- return runState & ACTIVE_COUNT_MASK;
+ int r = parallelism + (int)(ctl >> AC_SHIFT) + blockedCount;
+ return r <= 0? 0 : r; // suppress momentarily negative values
}
/**
@@ -1619,7 +1739,7 @@
* @return {@code true} if all threads are currently idle
*/
public boolean isQuiescent() {
- return (runState & ACTIVE_COUNT_MASK) == 0;
+ return parallelism + (int)(ctl >> AC_SHIFT) + blockedCount == 0;
}
/**
@@ -1649,21 +1769,25 @@
*/
public long getQueuedTaskCount() {
long count = 0;
- for (ForkJoinWorkerThread w : workers)
- if (w != null)
- count += w.getQueueSize();
+ ForkJoinWorkerThread[] ws;
+ if ((short)(ctl >>> TC_SHIFT) > -parallelism &&
+ (ws = workers) != null) {
+ for (ForkJoinWorkerThread w : ws)
+ if (w != null)
+ count -= w.queueBase - w.queueTop; // must read base first
+ }
return count;
}
/**
* Returns an estimate of the number of tasks submitted to this
- * pool that have not yet begun executing. This method takes time
- * proportional to the number of submissions.
+ * pool that have not yet begun executing. This method may take
+ * time proportional to the number of submissions.
*
* @return the number of queued submissions
*/
public int getQueuedSubmissionCount() {
- return submissionQueue.size();
+ return -queueBase + queueTop;
}
/**
@@ -1673,7 +1797,7 @@
* @return {@code true} if there are any queued submissions
*/
public boolean hasQueuedSubmissions() {
- return !submissionQueue.isEmpty();
+ return queueBase != queueTop;
}
/**
@@ -1684,7 +1808,19 @@
* @return the next submission, or {@code null} if none
*/
protected ForkJoinTask> pollSubmission() {
- return submissionQueue.poll();
+ ForkJoinTask> t; ForkJoinTask>[] q; int b, i;
+ while ((b = queueBase) != queueTop &&
+ (q = submissionQueue) != null &&
+ (i = (q.length - 1) & b) >= 0) {
+ long u = (i << ASHIFT) + ABASE;
+ if ((t = q[i]) != null &&
+ queueBase == b &&
+ UNSAFE.compareAndSwapObject(q, u, t, null)) {
+ queueBase = b + 1;
+ return t;
+ }
+ }
+ return null;
}
/**
@@ -1705,10 +1841,21 @@
* @return the number of elements transferred
*/
protected int drainTasksTo(Collection super ForkJoinTask>> c) {
- int count = submissionQueue.drainTo(c);
- for (ForkJoinWorkerThread w : workers)
- if (w != null)
- count += w.drainTasksTo(c);
+ int count = 0;
+ while (queueBase != queueTop) {
+ ForkJoinTask> t = pollSubmission();
+ if (t != null) {
+ c.add(t);
+ ++count;
+ }
+ }
+ ForkJoinWorkerThread[] ws;
+ if ((short)(ctl >>> TC_SHIFT) > -parallelism &&
+ (ws = workers) != null) {
+ for (ForkJoinWorkerThread w : ws)
+ if (w != null)
+ count += w.drainTasksTo(c);
+ }
return count;
}
@@ -1723,14 +1870,20 @@
long st = getStealCount();
long qt = getQueuedTaskCount();
long qs = getQueuedSubmissionCount();
- int wc = workerCounts;
- int tc = wc >>> TOTAL_COUNT_SHIFT;
- int rc = wc & RUNNING_COUNT_MASK;
int pc = parallelism;
- int rs = runState;
- int ac = rs & ACTIVE_COUNT_MASK;
+ long c = ctl;
+ int tc = pc + (short)(c >>> TC_SHIFT);
+ int rc = pc + (int)(c >> AC_SHIFT);
+ if (rc < 0) // ignore transient negative
+ rc = 0;
+ int ac = rc + blockedCount;
+ String level;
+ if ((c & STOP_BIT) != 0)
+ level = (tc == 0)? "Terminated" : "Terminating";
+ else
+ level = shutdown? "Shutting down" : "Running";
return super.toString() +
- "[" + runLevelToString(rs) +
+ "[" + level +
", parallelism = " + pc +
", size = " + tc +
", active = " + ac +
@@ -1741,13 +1894,6 @@
"]";
}
- private static String runLevelToString(int s) {
- return ((s & TERMINATED) != 0 ? "Terminated" :
- ((s & TERMINATING) != 0 ? "Terminating" :
- ((s & SHUTDOWN) != 0 ? "Shutting down" :
- "Running")));
- }
-
/**
* Initiates an orderly shutdown in which previously submitted
* tasks are executed, but no new tasks will be accepted.
@@ -1762,7 +1908,7 @@
*/
public void shutdown() {
checkPermission();
- advanceRunLevel(SHUTDOWN);
+ shutdown = true;
tryTerminate(false);
}
@@ -1784,6 +1930,7 @@
*/
public List shutdownNow() {
checkPermission();
+ shutdown = true;
tryTerminate(true);
return Collections.emptyList();
}
@@ -1794,7 +1941,9 @@
* @return {@code true} if all tasks have completed following shut down
*/
public boolean isTerminated() {
- return runState >= TERMINATED;
+ long c = ctl;
+ return ((c & STOP_BIT) != 0L &&
+ (short)(c >>> TC_SHIFT) == -parallelism);
}
/**
@@ -1811,14 +1960,16 @@
* @return {@code true} if terminating but not yet terminated
*/
public boolean isTerminating() {
- return (runState & (TERMINATING|TERMINATED)) == TERMINATING;
+ long c = ctl;
+ return ((c & STOP_BIT) != 0L &&
+ (short)(c >>> TC_SHIFT) != -parallelism);
}
/**
* Returns true if terminating or terminated. Used by ForkJoinWorkerThread.
*/
final boolean isAtLeastTerminating() {
- return runState >= TERMINATING;
+ return (ctl & STOP_BIT) != 0L;
}
/**
@@ -1827,7 +1978,7 @@
* @return {@code true} if this pool has been shut down
*/
public boolean isShutdown() {
- return runState >= SHUTDOWN;
+ return shutdown;
}
/**
@@ -1843,12 +1994,20 @@
*/
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
+ long nanos = unit.toNanos(timeout);
+ final ReentrantLock lock = this.submissionLock;
+ lock.lock();
try {
- termination.awaitAdvanceInterruptibly(0, timeout, unit);
- } catch (TimeoutException ex) {
- return false;
+ for (;;) {
+ if (isTerminated())
+ return true;
+ if (nanos <= 0)
+ return false;
+ nanos = termination.awaitNanos(nanos);
+ }
+ } finally {
+ lock.unlock();
}
- return true;
}
/**
@@ -1859,13 +2018,15 @@
* {@code isReleasable} must return {@code true} if blocking is
* not necessary. Method {@code block} blocks the current thread
* if necessary (perhaps internally invoking {@code isReleasable}
- * before actually blocking). The unusual methods in this API
- * accommodate synchronizers that may, but don't usually, block
- * for long periods. Similarly, they allow more efficient internal
- * handling of cases in which additional workers may be, but
- * usually are not, needed to ensure sufficient parallelism.
- * Toward this end, implementations of method {@code isReleasable}
- * must be amenable to repeated invocation.
+ * before actually blocking). These actions are performed by any
+ * thread invoking {@link ForkJoinPool#managedBlock}. The
+ * unusual methods in this API accommodate synchronizers that may,
+ * but don't usually, block for long periods. Similarly, they
+ * allow more efficient internal handling of cases in which
+ * additional workers may be, but usually are not, needed to
+ * ensure sufficient parallelism. Toward this end,
+ * implementations of method {@code isReleasable} must be amenable
+ * to repeated invocation.
*
* For example, here is a ManagedBlocker based on a
* ReentrantLock:
@@ -1967,29 +2128,47 @@
}
// Unsafe mechanics
+ private static final sun.misc.Unsafe UNSAFE;
+ private static final long ctlOffset;
+ private static final long stealCountOffset;
+ private static final long blockedCountOffset;
+ private static final long quiescerCountOffset;
+ private static final long scanGuardOffset;
+ private static final long nextWorkerNumberOffset;
+ private static final long ABASE;
+ private static final int ASHIFT;
- private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
- private static final long workerCountsOffset =
- objectFieldOffset("workerCounts", ForkJoinPool.class);
- private static final long runStateOffset =
- objectFieldOffset("runState", ForkJoinPool.class);
- private static final long eventCountOffset =
- objectFieldOffset("eventCount", ForkJoinPool.class);
- private static final long eventWaitersOffset =
- objectFieldOffset("eventWaiters", ForkJoinPool.class);
- private static final long stealCountOffset =
- objectFieldOffset("stealCount", ForkJoinPool.class);
- private static final long spareWaitersOffset =
- objectFieldOffset("spareWaiters", ForkJoinPool.class);
+ static {
+ poolNumberGenerator = new AtomicInteger();
+ workerSeedGenerator = new Random();
+ modifyThreadPermission = new RuntimePermission("modifyThread");
+ defaultForkJoinWorkerThreadFactory =
+ new DefaultForkJoinWorkerThreadFactory();
+ int s;
+ try {
+ UNSAFE = sun.misc.Unsafe.getUnsafe();
+ Class k = ForkJoinPool.class;
+ ctlOffset = UNSAFE.objectFieldOffset
+ (k.getDeclaredField("ctl"));
+ stealCountOffset = UNSAFE.objectFieldOffset
+ (k.getDeclaredField("stealCount"));
+ blockedCountOffset = UNSAFE.objectFieldOffset
+ (k.getDeclaredField("blockedCount"));
+ quiescerCountOffset = UNSAFE.objectFieldOffset
+ (k.getDeclaredField("quiescerCount"));
+ scanGuardOffset = UNSAFE.objectFieldOffset
+ (k.getDeclaredField("scanGuard"));
+ nextWorkerNumberOffset = UNSAFE.objectFieldOffset
+ (k.getDeclaredField("nextWorkerNumber"));
+ Class a = ForkJoinTask[].class;
+ ABASE = UNSAFE.arrayBaseOffset(a);
+ s = UNSAFE.arrayIndexScale(a);
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ if ((s & (s-1)) != 0)
+ throw new Error("data type scale not a power of two");
+ ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
+ }
- private static long objectFieldOffset(String field, Class> klazz) {
- try {
- return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
- } catch (NoSuchFieldException e) {
- // Convert Exception to corresponding Error
- NoSuchFieldError error = new NoSuchFieldError(field);
- error.initCause(e);
- throw error;
- }
- }
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Wed Jul 05 17:39:17 2017 +0200
@@ -41,7 +41,8 @@
import java.util.List;
import java.util.RandomAccess;
import java.util.Map;
-import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
+import java.lang.ref.ReferenceQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
@@ -52,6 +53,8 @@
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.concurrent.locks.ReentrantLock;
+import java.lang.reflect.Constructor;
/**
* Abstract base class for tasks that run within a {@link ForkJoinPool}.
@@ -95,7 +98,11 @@
* rethrown to callers attempting to join them. These exceptions may
* additionally include {@link RejectedExecutionException} stemming
* from internal resource exhaustion, such as failure to allocate
- * internal task queues.
+ * internal task queues. Rethrown exceptions behave in the same way as
+ * regular exceptions, but, when possible, contain stack traces (as
+ * displayed for example using {@code ex.printStackTrace()}) of both
+ * the thread that initiated the computation as well as the thread
+ * actually encountering the exception; minimally only the latter.
*
*
The primary method for awaiting completion and extracting
* results of a task is {@link #join}, but there are several variants:
@@ -192,8 +199,7 @@
* status maintenance (2) execution and awaiting completion (3)
* user-level methods that additionally report results. This is
* sometimes hard to see because this file orders exported methods
- * in a way that flows well in javadocs. In particular, most
- * join mechanics are in method quietlyJoin, below.
+ * in a way that flows well in javadocs.
*/
/*
@@ -215,91 +221,67 @@
/** The run status of this task */
volatile int status; // accessed directly by pool and workers
-
private static final int NORMAL = -1;
private static final int CANCELLED = -2;
private static final int EXCEPTIONAL = -3;
private static final int SIGNAL = 1;
/**
- * Table of exceptions thrown by tasks, to enable reporting by
- * callers. Because exceptions are rare, we don't directly keep
- * them with task objects, but instead use a weak ref table. Note
- * that cancellation exceptions don't appear in the table, but are
- * instead recorded as status values.
- * TODO: Use ConcurrentReferenceHashMap
- */
- static final Map, Throwable> exceptionMap =
- Collections.synchronizedMap
- (new WeakHashMap, Throwable>());
-
- // Maintaining completion status
-
- /**
* Marks completion and wakes up threads waiting to join this task,
* also clearing signal request bits.
*
* @param completion one of NORMAL, CANCELLED, EXCEPTIONAL
+ * @return completion status on exit
*/
- private void setCompletion(int completion) {
- int s;
- while ((s = status) >= 0) {
+ private int setCompletion(int completion) {
+ for (int s;;) {
+ if ((s = status) < 0)
+ return s;
if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) {
if (s != 0)
synchronized (this) { notifyAll(); }
- break;
+ return completion;
}
}
}
/**
- * Records exception and sets exceptional completion.
+ * Tries to block a worker thread until completed or timed out.
+ * Uses Object.wait time argument conventions.
+ * May fail on contention or interrupt.
*
- * @return status on exit
+ * @param millis if > 0, wait time.
*/
- private void setExceptionalCompletion(Throwable rex) {
- exceptionMap.put(this, rex);
- setCompletion(EXCEPTIONAL);
- }
-
- /**
- * Blocks a worker thread until completed or timed out. Called
- * only by pool.
- */
- final void internalAwaitDone(long millis, int nanos) {
- int s = status;
- if ((s == 0 &&
- UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL)) ||
- s > 0) {
- try { // the odd construction reduces lock bias effects
+ final void tryAwaitDone(long millis) {
+ int s;
+ try {
+ if (((s = status) > 0 ||
+ (s == 0 &&
+ UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL))) &&
+ status > 0) {
synchronized (this) {
if (status > 0)
- wait(millis, nanos);
- else
- notifyAll();
+ wait(millis);
}
- } catch (InterruptedException ie) {
- cancelIfTerminating();
}
+ } catch (InterruptedException ie) {
+ // caller must check termination
}
}
/**
* Blocks a non-worker-thread until completion.
+ * @return status upon completion
*/
- private void externalAwaitDone() {
- if (status >= 0) {
+ private int externalAwaitDone() {
+ int s;
+ if ((s = status) >= 0) {
boolean interrupted = false;
synchronized (this) {
- for (;;) {
- int s = status;
+ while ((s = status) >= 0) {
if (s == 0)
UNSAFE.compareAndSwapInt(this, statusOffset,
0, SIGNAL);
- else if (s < 0) {
- notifyAll();
- break;
- }
else {
try {
wait();
@@ -312,53 +294,308 @@
if (interrupted)
Thread.currentThread().interrupt();
}
+ return s;
}
/**
* Blocks a non-worker-thread until completion or interruption or timeout.
*/
- private void externalInterruptibleAwaitDone(boolean timed, long nanos)
+ private int externalInterruptibleAwaitDone(long millis)
throws InterruptedException {
+ int s;
if (Thread.interrupted())
throw new InterruptedException();
- if (status >= 0) {
- long startTime = timed ? System.nanoTime() : 0L;
+ if ((s = status) >= 0) {
synchronized (this) {
- for (;;) {
- long nt;
- int s = status;
+ while ((s = status) >= 0) {
if (s == 0)
UNSAFE.compareAndSwapInt(this, statusOffset,
0, SIGNAL);
- else if (s < 0) {
- notifyAll();
+ else {
+ wait(millis);
+ if (millis > 0L)
+ break;
+ }
+ }
+ }
+ }
+ return s;
+ }
+
+ /**
+ * Primary execution method for stolen tasks. Unless done, calls
+ * exec and records status if completed, but doesn't wait for
+ * completion otherwise.
+ */
+ final void doExec() {
+ if (status >= 0) {
+ boolean completed;
+ try {
+ completed = exec();
+ } catch (Throwable rex) {
+ setExceptionalCompletion(rex);
+ return;
+ }
+ if (completed)
+ setCompletion(NORMAL); // must be outside try block
+ }
+ }
+
+ /**
+ * Primary mechanics for join, get, quietlyJoin.
+ * @return status upon completion
+ */
+ private int doJoin() {
+ Thread t; ForkJoinWorkerThread w; int s; boolean completed;
+ if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) {
+ if ((s = status) < 0)
+ return s;
+ if ((w = (ForkJoinWorkerThread)t).unpushTask(this)) {
+ try {
+ completed = exec();
+ } catch (Throwable rex) {
+ return setExceptionalCompletion(rex);
+ }
+ if (completed)
+ return setCompletion(NORMAL);
+ }
+ return w.joinTask(this);
+ }
+ else
+ return externalAwaitDone();
+ }
+
+ /**
+ * Primary mechanics for invoke, quietlyInvoke.
+ * @return status upon completion
+ */
+ private int doInvoke() {
+ int s; boolean completed;
+ if ((s = status) < 0)
+ return s;
+ try {
+ completed = exec();
+ } catch (Throwable rex) {
+ return setExceptionalCompletion(rex);
+ }
+ if (completed)
+ return setCompletion(NORMAL);
+ else
+ return doJoin();
+ }
+
+ // Exception table support
+
+ /**
+ * Table of exceptions thrown by tasks, to enable reporting by
+ * callers. Because exceptions are rare, we don't directly keep
+ * them with task objects, but instead use a weak ref table. Note
+ * that cancellation exceptions don't appear in the table, but are
+ * instead recorded as status values.
+ *
+ * Note: These statics are initialized below in static block.
+ */
+ private static final ExceptionNode[] exceptionTable;
+ private static final ReentrantLock exceptionTableLock;
+ private static final ReferenceQueue exceptionTableRefQueue;
+
+ /**
+ * Fixed capacity for exceptionTable.
+ */
+ private static final int EXCEPTION_MAP_CAPACITY = 32;
+
+ /**
+ * Key-value nodes for exception table. The chained hash table
+ * uses identity comparisons, full locking, and weak references
+ * for keys. The table has a fixed capacity because it only
+ * maintains task exceptions long enough for joiners to access
+ * them, so should never become very large for sustained
+ * periods. However, since we do not know when the last joiner
+ * completes, we must use weak references and expunge them. We do
+ * so on each operation (hence full locking). Also, some thread in
+ * any ForkJoinPool will call helpExpungeStaleExceptions when its
+ * pool becomes isQuiescent.
+ */
+ static final class ExceptionNode extends WeakReference>{
+ final Throwable ex;
+ ExceptionNode next;
+ final long thrower; // use id not ref to avoid weak cycles
+ ExceptionNode(ForkJoinTask> task, Throwable ex, ExceptionNode next) {
+ super(task, exceptionTableRefQueue);
+ this.ex = ex;
+ this.next = next;
+ this.thrower = Thread.currentThread().getId();
+ }
+ }
+
+ /**
+ * Records exception and sets exceptional completion.
+ *
+ * @return status on exit
+ */
+ private int setExceptionalCompletion(Throwable ex) {
+ int h = System.identityHashCode(this);
+ final ReentrantLock lock = exceptionTableLock;
+ lock.lock();
+ try {
+ expungeStaleExceptions();
+ ExceptionNode[] t = exceptionTable;
+ int i = h & (t.length - 1);
+ for (ExceptionNode e = t[i]; ; e = e.next) {
+ if (e == null) {
+ t[i] = new ExceptionNode(this, ex, t[i]);
+ break;
+ }
+ if (e.get() == this) // already present
+ break;
+ }
+ } finally {
+ lock.unlock();
+ }
+ return setCompletion(EXCEPTIONAL);
+ }
+
+ /**
+ * Removes exception node and clears status
+ */
+ private void clearExceptionalCompletion() {
+ int h = System.identityHashCode(this);
+ final ReentrantLock lock = exceptionTableLock;
+ lock.lock();
+ try {
+ ExceptionNode[] t = exceptionTable;
+ int i = h & (t.length - 1);
+ ExceptionNode e = t[i];
+ ExceptionNode pred = null;
+ while (e != null) {
+ ExceptionNode next = e.next;
+ if (e.get() == this) {
+ if (pred == null)
+ t[i] = next;
+ else
+ pred.next = next;
+ break;
+ }
+ pred = e;
+ e = next;
+ }
+ expungeStaleExceptions();
+ status = 0;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns a rethrowable exception for the given task, if
+ * available. To provide accurate stack traces, if the exception
+ * was not thrown by the current thread, we try to create a new
+ * exception of the same type as the one thrown, but with the
+ * recorded exception as its cause. If there is no such
+ * constructor, we instead try to use a no-arg constructor,
+ * followed by initCause, to the same effect. If none of these
+ * apply, or any fail due to other exceptions, we return the
+ * recorded exception, which is still correct, although it may
+ * contain a misleading stack trace.
+ *
+ * @return the exception, or null if none
+ */
+ private Throwable getThrowableException() {
+ if (status != EXCEPTIONAL)
+ return null;
+ int h = System.identityHashCode(this);
+ ExceptionNode e;
+ final ReentrantLock lock = exceptionTableLock;
+ lock.lock();
+ try {
+ expungeStaleExceptions();
+ ExceptionNode[] t = exceptionTable;
+ e = t[h & (t.length - 1)];
+ while (e != null && e.get() != this)
+ e = e.next;
+ } finally {
+ lock.unlock();
+ }
+ Throwable ex;
+ if (e == null || (ex = e.ex) == null)
+ return null;
+ if (e.thrower != Thread.currentThread().getId()) {
+ Class ec = ex.getClass();
+ try {
+ Constructor> noArgCtor = null;
+ Constructor>[] cs = ec.getConstructors();// public ctors only
+ for (int i = 0; i < cs.length; ++i) {
+ Constructor> c = cs[i];
+ Class>[] ps = c.getParameterTypes();
+ if (ps.length == 0)
+ noArgCtor = c;
+ else if (ps.length == 1 && ps[0] == Throwable.class)
+ return (Throwable)(c.newInstance(ex));
+ }
+ if (noArgCtor != null) {
+ Throwable wx = (Throwable)(noArgCtor.newInstance());
+ wx.initCause(ex);
+ return wx;
+ }
+ } catch (Exception ignore) {
+ }
+ }
+ return ex;
+ }
+
+ /**
+ * Poll stale refs and remove them. Call only while holding lock.
+ */
+ private static void expungeStaleExceptions() {
+ for (Object x; (x = exceptionTableRefQueue.poll()) != null;) {
+ if (x instanceof ExceptionNode) {
+ ForkJoinTask> key = ((ExceptionNode)x).get();
+ ExceptionNode[] t = exceptionTable;
+ int i = System.identityHashCode(key) & (t.length - 1);
+ ExceptionNode e = t[i];
+ ExceptionNode pred = null;
+ while (e != null) {
+ ExceptionNode next = e.next;
+ if (e == x) {
+ if (pred == null)
+ t[i] = next;
+ else
+ pred.next = next;
break;
}
- else if (!timed)
- wait();
- else if ((nt = nanos - (System.nanoTime()-startTime)) > 0L)
- wait(nt / 1000000, (int)(nt % 1000000));
- else
- break;
+ pred = e;
+ e = next;
}
}
}
}
/**
- * Unless done, calls exec and records status if completed, but
- * doesn't wait for completion otherwise. Primary execution method
- * for ForkJoinWorkerThread.
+ * If lock is available, poll stale refs and remove them.
+ * Called from ForkJoinPool when pools become quiescent.
*/
- final void quietlyExec() {
- try {
- if (status < 0 || !exec())
- return;
- } catch (Throwable rex) {
- setExceptionalCompletion(rex);
- return;
+ static final void helpExpungeStaleExceptions() {
+ final ReentrantLock lock = exceptionTableLock;
+ if (lock.tryLock()) {
+ try {
+ expungeStaleExceptions();
+ } finally {
+ lock.unlock();
+ }
}
- setCompletion(NORMAL); // must be outside try block
+ }
+
+ /**
+ * Report the result of invoke or join; called only upon
+ * non-normal return of internal versions.
+ */
+ private V reportResult() {
+ int s; Throwable ex;
+ if ((s = status) == CANCELLED)
+ throw new CancellationException();
+ if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
+ UNSAFE.throwException(ex);
+ return getRawResult();
}
// public methods
@@ -399,11 +636,10 @@
* @return the computed result
*/
public final V join() {
- quietlyJoin();
- Throwable ex;
- if (status < NORMAL && (ex = getException()) != null)
- UNSAFE.throwException(ex);
- return getRawResult();
+ if (doJoin() != NORMAL)
+ return reportResult();
+ else
+ return getRawResult();
}
/**
@@ -415,11 +651,10 @@
* @return the computed result
*/
public final V invoke() {
- quietlyInvoke();
- Throwable ex;
- if (status < NORMAL && (ex = getException()) != null)
- UNSAFE.throwException(ex);
- return getRawResult();
+ if (doInvoke() != NORMAL)
+ return reportResult();
+ else
+ return getRawResult();
}
/**
@@ -483,22 +718,16 @@
}
else if (i != 0)
t.fork();
- else {
- t.quietlyInvoke();
- if (ex == null && t.status < NORMAL)
- ex = t.getException();
- }
+ else if (t.doInvoke() < NORMAL && ex == null)
+ ex = t.getException();
}
for (int i = 1; i <= last; ++i) {
ForkJoinTask> t = tasks[i];
if (t != null) {
if (ex != null)
t.cancel(false);
- else {
- t.quietlyJoin();
- if (ex == null && t.status < NORMAL)
- ex = t.getException();
- }
+ else if (t.doJoin() < NORMAL && ex == null)
+ ex = t.getException();
}
}
if (ex != null)
@@ -546,22 +775,16 @@
}
else if (i != 0)
t.fork();
- else {
- t.quietlyInvoke();
- if (ex == null && t.status < NORMAL)
- ex = t.getException();
- }
+ else if (t.doInvoke() < NORMAL && ex == null)
+ ex = t.getException();
}
for (int i = 1; i <= last; ++i) {
ForkJoinTask> t = ts.get(i);
if (t != null) {
if (ex != null)
t.cancel(false);
- else {
- t.quietlyJoin();
- if (ex == null && t.status < NORMAL)
- ex = t.getException();
- }
+ else if (t.doJoin() < NORMAL && ex == null)
+ ex = t.getException();
}
}
if (ex != null)
@@ -597,8 +820,7 @@
* @return {@code true} if this task is now cancelled
*/
public boolean cancel(boolean mayInterruptIfRunning) {
- setCompletion(CANCELLED);
- return status == CANCELLED;
+ return setCompletion(CANCELLED) == CANCELLED;
}
/**
@@ -614,21 +836,6 @@
}
}
- /**
- * Cancels if current thread is a terminating worker thread,
- * ignoring any exceptions thrown by cancel.
- */
- final void cancelIfTerminating() {
- Thread t = Thread.currentThread();
- if ((t instanceof ForkJoinWorkerThread) &&
- ((ForkJoinWorkerThread) t).isTerminating()) {
- try {
- cancel(false);
- } catch (Throwable ignore) {
- }
- }
- }
-
public final boolean isDone() {
return status < 0;
}
@@ -668,7 +875,7 @@
int s = status;
return ((s >= NORMAL) ? null :
(s == CANCELLED) ? new CancellationException() :
- exceptionMap.get(this));
+ getThrowableException());
}
/**
@@ -726,19 +933,13 @@
* member of a ForkJoinPool and was interrupted while waiting
*/
public final V get() throws InterruptedException, ExecutionException {
- Thread t = Thread.currentThread();
- if (t instanceof ForkJoinWorkerThread)
- quietlyJoin();
- else
- externalInterruptibleAwaitDone(false, 0L);
- int s = status;
- if (s != NORMAL) {
- Throwable ex;
- if (s == CANCELLED)
- throw new CancellationException();
- if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
- throw new ExecutionException(ex);
- }
+ int s = (Thread.currentThread() instanceof ForkJoinWorkerThread) ?
+ doJoin() : externalInterruptibleAwaitDone(0L);
+ Throwable ex;
+ if (s == CANCELLED)
+ throw new CancellationException();
+ if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
+ throw new ExecutionException(ex);
return getRawResult();
}
@@ -758,20 +959,39 @@
*/
public final V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
- long nanos = unit.toNanos(timeout);
Thread t = Thread.currentThread();
- if (t instanceof ForkJoinWorkerThread)
- ((ForkJoinWorkerThread)t).joinTask(this, true, nanos);
- else
- externalInterruptibleAwaitDone(true, nanos);
+ if (t instanceof ForkJoinWorkerThread) {
+ ForkJoinWorkerThread w = (ForkJoinWorkerThread) t;
+ long nanos = unit.toNanos(timeout);
+ if (status >= 0) {
+ boolean completed = false;
+ if (w.unpushTask(this)) {
+ try {
+ completed = exec();
+ } catch (Throwable rex) {
+ setExceptionalCompletion(rex);
+ }
+ }
+ if (completed)
+ setCompletion(NORMAL);
+ else if (status >= 0 && nanos > 0)
+ w.pool.timedAwaitJoin(this, nanos);
+ }
+ }
+ else {
+ long millis = unit.toMillis(timeout);
+ if (millis > 0)
+ externalInterruptibleAwaitDone(millis);
+ }
int s = status;
if (s != NORMAL) {
Throwable ex;
if (s == CANCELLED)
throw new CancellationException();
- if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
+ if (s != EXCEPTIONAL)
+ throw new TimeoutException();
+ if ((ex = getThrowableException()) != null)
throw new ExecutionException(ex);
- throw new TimeoutException();
}
return getRawResult();
}
@@ -783,28 +1003,7 @@
* known to have aborted.
*/
public final void quietlyJoin() {
- Thread t;
- if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) {
- ForkJoinWorkerThread w = (ForkJoinWorkerThread) t;
- if (status >= 0) {
- if (w.unpushTask(this)) {
- boolean completed;
- try {
- completed = exec();
- } catch (Throwable rex) {
- setExceptionalCompletion(rex);
- return;
- }
- if (completed) {
- setCompletion(NORMAL);
- return;
- }
- }
- w.joinTask(this, false, 0L);
- }
- }
- else
- externalAwaitDone();
+ doJoin();
}
/**
@@ -813,19 +1012,7 @@
* exception.
*/
public final void quietlyInvoke() {
- if (status >= 0) {
- boolean completed;
- try {
- completed = exec();
- } catch (Throwable rex) {
- setExceptionalCompletion(rex);
- return;
- }
- if (completed)
- setCompletion(NORMAL);
- else
- quietlyJoin();
- }
+ doInvoke();
}
/**
@@ -864,8 +1051,9 @@
*/
public void reinitialize() {
if (status == EXCEPTIONAL)
- exceptionMap.remove(this);
- status = 0;
+ clearExceptionalCompletion();
+ else
+ status = 0;
}
/**
@@ -1176,23 +1364,23 @@
s.defaultReadObject();
Object ex = s.readObject();
if (ex != null)
- setExceptionalCompletion((Throwable) ex);
+ setExceptionalCompletion((Throwable)ex);
}
// Unsafe mechanics
-
- private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
- private static final long statusOffset =
- objectFieldOffset("status", ForkJoinTask.class);
-
- private static long objectFieldOffset(String field, Class> klazz) {
+ private static final sun.misc.Unsafe UNSAFE;
+ private static final long statusOffset;
+ static {
+ exceptionTableLock = new ReentrantLock();
+ exceptionTableRefQueue = new ReferenceQueue();
+ exceptionTable = new ExceptionNode[EXCEPTION_MAP_CAPACITY];
try {
- return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
- } catch (NoSuchFieldException e) {
- // Convert Exception to corresponding Error
- NoSuchFieldError error = new NoSuchFieldError(field);
- error.initCause(e);
- throw error;
+ UNSAFE = sun.misc.Unsafe.getUnsafe();
+ statusOffset = UNSAFE.objectFieldOffset
+ (ForkJoinTask.class.getDeclaredField("status"));
+ } catch (Exception e) {
+ throw new Error(e);
}
}
+
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Wed Jul 05 17:39:17 2017 +0200
@@ -35,9 +35,7 @@
package java.util.concurrent;
-import java.util.Random;
import java.util.Collection;
-import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.RejectedExecutionException;
/**
@@ -84,33 +82,38 @@
* a footprint as possible even in programs generating huge
* numbers of tasks. To accomplish this, we shift the CAS
* arbitrating pop vs deq (steal) from being on the indices
- * ("base" and "sp") to the slots themselves (mainly via method
- * "casSlotNull()"). So, both a successful pop and deq mainly
- * entail a CAS of a slot from non-null to null. Because we rely
- * on CASes of references, we do not need tag bits on base or sp.
- * They are simple ints as used in any circular array-based queue
- * (see for example ArrayDeque). Updates to the indices must
- * still be ordered in a way that guarantees that sp == base means
- * the queue is empty, but otherwise may err on the side of
- * possibly making the queue appear nonempty when a push, pop, or
- * deq have not fully committed. Note that this means that the deq
- * operation, considered individually, is not wait-free. One thief
- * cannot successfully continue until another in-progress one (or,
- * if previously empty, a push) completes. However, in the
+ * ("queueBase" and "queueTop") to the slots themselves (mainly
+ * via method "casSlotNull()"). So, both a successful pop and deq
+ * mainly entail a CAS of a slot from non-null to null. Because
+ * we rely on CASes of references, we do not need tag bits on
+ * queueBase or queueTop. They are simple ints as used in any
+ * circular array-based queue (see for example ArrayDeque).
+ * Updates to the indices must still be ordered in a way that
+ * guarantees that queueTop == queueBase means the queue is empty,
+ * but otherwise may err on the side of possibly making the queue
+ * appear nonempty when a push, pop, or deq have not fully
+ * committed. Note that this means that the deq operation,
+ * considered individually, is not wait-free. One thief cannot
+ * successfully continue until another in-progress one (or, if
+ * previously empty, a push) completes. However, in the
* aggregate, we ensure at least probabilistic non-blockingness.
* If an attempted steal fails, a thief always chooses a different
* random victim target to try next. So, in order for one thief to
* progress, it suffices for any in-progress deq or new push on
- * any empty queue to complete. One reason this works well here is
- * that apparently-nonempty often means soon-to-be-stealable,
- * which gives threads a chance to set activation status if
- * necessary before stealing.
+ * any empty queue to complete.
*
* This approach also enables support for "async mode" where local
* task processing is in FIFO, not LIFO order; simply by using a
* version of deq rather than pop when locallyFifo is true (as set
* by the ForkJoinPool). This allows use in message-passing
- * frameworks in which tasks are never joined.
+ * frameworks in which tasks are never joined. However neither
+ * mode considers affinities, loads, cache localities, etc, so
+ * rarely provide the best possible performance on a given
+ * machine, but portably provide good throughput by averaging over
+ * these factors. (Further, even if we did try to use such
+ * information, we do not usually have a basis for exploiting
+ * it. For example, some sets of tasks profit from cache
+ * affinities, but others are harmed by cache pollution effects.)
*
* When a worker would otherwise be blocked waiting to join a
* task, it first tries a form of linear helping: Each worker
@@ -137,29 +140,26 @@
* miss links in the chain during long-lived tasks, GC stalls etc
* (which is OK since blocking in such cases is usually a good
* idea). (4) We bound the number of attempts to find work (see
- * MAX_HELP_DEPTH) and fall back to suspending the worker and if
- * necessary replacing it with a spare (see
- * ForkJoinPool.awaitJoin).
+ * MAX_HELP) and fall back to suspending the worker and if
+ * necessary replacing it with another.
*
* Efficient implementation of these algorithms currently relies
* on an uncomfortable amount of "Unsafe" mechanics. To maintain
- * correct orderings, reads and writes of variable base require
- * volatile ordering. Variable sp does not require volatile
- * writes but still needs store-ordering, which we accomplish by
- * pre-incrementing sp before filling the slot with an ordered
- * store. (Pre-incrementing also enables backouts used in
- * joinTask.) Because they are protected by volatile base reads,
- * reads of the queue array and its slots by other threads do not
- * need volatile load semantics, but writes (in push) require
- * store order and CASes (in pop and deq) require (volatile) CAS
- * semantics. (Michael, Saraswat, and Vechev's algorithm has
- * similar properties, but without support for nulling slots.)
- * Since these combinations aren't supported using ordinary
- * volatiles, the only way to accomplish these efficiently is to
- * use direct Unsafe calls. (Using external AtomicIntegers and
- * AtomicReferenceArrays for the indices and array is
- * significantly slower because of memory locality and indirection
- * effects.)
+ * correct orderings, reads and writes of variable queueBase
+ * require volatile ordering. Variable queueTop need not be
+ * volatile because non-local reads always follow those of
+ * queueBase. Similarly, because they are protected by volatile
+ * queueBase reads, reads of the queue array and its slots by
+ * other threads do not need volatile load semantics, but writes
+ * (in push) require store order and CASes (in pop and deq)
+ * require (volatile) CAS semantics. (Michael, Saraswat, and
+ * Vechev's algorithm has similar properties, but without support
+ * for nulling slots.) Since these combinations aren't supported
+ * using ordinary volatiles, the only way to accomplish these
+ * efficiently is to use direct Unsafe calls. (Using external
+ * AtomicIntegers and AtomicReferenceArrays for the indices and
+ * array is significantly slower because of memory locality and
+ * indirection effects.)
*
* Further, performance on most platforms is very sensitive to
* placement and sizing of the (resizable) queue array. Even
@@ -167,30 +167,13 @@
* initial size must be large enough to counteract cache
* contention effects across multiple queues (especially in the
* presence of GC cardmarking). Also, to improve thread-locality,
- * queues are initialized after starting. All together, these
- * low-level implementation choices produce as much as a factor of
- * 4 performance improvement compared to naive implementations,
- * and enable the processing of billions of tasks per second,
- * sometimes at the expense of ugliness.
+ * queues are initialized after starting.
*/
/**
- * Generator for initial random seeds for random victim
- * selection. This is used only to create initial seeds. Random
- * steals use a cheaper xorshift generator per steal attempt. We
- * expect only rare contention on seedGenerator, so just use a
- * plain Random.
+ * Mask for pool indices encoded as shorts
*/
- private static final Random seedGenerator = new Random();
-
- /**
- * The maximum stolen->joining link depth allowed in helpJoinTask.
- * Depths for legitimate chains are unbounded, but we use a fixed
- * constant to avoid (otherwise unchecked) cycles and bound
- * staleness of traversal parameters at the expense of sometimes
- * blocking when we could be helping.
- */
- private static final int MAX_HELP_DEPTH = 8;
+ private static final int SMASK = 0xffff;
/**
* Capacity of work-stealing queue array upon initialization.
@@ -200,12 +183,19 @@
private static final int INITIAL_QUEUE_CAPACITY = 1 << 13;
/**
- * Maximum work-stealing queue array size. Must be less than or
- * equal to 1 << (31 - width of array entry) to ensure lack of
- * index wraparound. The value is set in the static block
- * at the end of this file after obtaining width.
+ * Maximum size for queue array. Must be a power of two
+ * less than or equal to 1 << (31 - width of array entry) to
+ * ensure lack of index wraparound, but is capped at a lower
+ * value to help users trap runaway computations.
*/
- private static final int MAXIMUM_QUEUE_CAPACITY;
+ private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M
+
+ /**
+ * The work-stealing queue array. Size must be a power of two.
+ * Initialized when started (as oposed to when constructed), to
+ * improve memory locality.
+ */
+ ForkJoinTask>[] queue;
/**
* The pool this thread works in. Accessed directly by ForkJoinTask.
@@ -213,25 +203,19 @@
final ForkJoinPool pool;
/**
- * The work-stealing queue array. Size must be a power of two.
- * Initialized in onStart, to improve memory locality.
+ * Index (mod queue.length) of next queue slot to push to or pop
+ * from. It is written only by owner thread, and accessed by other
+ * threads only after reading (volatile) queueBase. Both queueTop
+ * and queueBase are allowed to wrap around on overflow, but
+ * (queueTop - queueBase) still estimates size.
*/
- private ForkJoinTask>[] queue;
+ int queueTop;
/**
* Index (mod queue.length) of least valid queue slot, which is
* always the next position to steal from if nonempty.
*/
- private volatile int base;
-
- /**
- * Index (mod queue.length) of next queue slot to push to or pop
- * from. It is written only by owner thread, and accessed by other
- * threads only after reading (volatile) base. Both sp and base
- * are allowed to wrap around on overflow, but (sp - base) still
- * estimates size.
- */
- private int sp;
+ volatile int queueBase;
/**
* The index of most recent stealer, used as a hint to avoid
@@ -240,92 +224,68 @@
* of them (usually the most current). Declared non-volatile,
* relying on other prevailing sync to keep reasonably current.
*/
- private int stealHint;
-
- /**
- * Run state of this worker. In addition to the usual run levels,
- * tracks if this worker is suspended as a spare, and if it was
- * killed (trimmed) while suspended. However, "active" status is
- * maintained separately and modified only in conjunction with
- * CASes of the pool's runState (which are currently sadly
- * manually inlined for performance.) Accessed directly by pool
- * to simplify checks for normal (zero) status.
- */
- volatile int runState;
-
- private static final int TERMINATING = 0x01;
- private static final int TERMINATED = 0x02;
- private static final int SUSPENDED = 0x04; // inactive spare
- private static final int TRIMMED = 0x08; // killed while suspended
-
- /**
- * Number of steals. Directly accessed (and reset) by
- * pool.tryAccumulateStealCount when idle.
- */
- int stealCount;
-
- /**
- * Seed for random number generator for choosing steal victims.
- * Uses Marsaglia xorshift. Must be initialized as nonzero.
- */
- private int seed;
-
- /**
- * Activity status. When true, this worker is considered active.
- * Accessed directly by pool. Must be false upon construction.
- */
- boolean active;
-
- /**
- * True if use local fifo, not default lifo, for local polling.
- * Shadows value from ForkJoinPool.
- */
- private final boolean locallyFifo;
+ int stealHint;
/**
* Index of this worker in pool array. Set once by pool before
* running, and accessed directly by pool to locate this worker in
* its workers array.
*/
- int poolIndex;
+ final int poolIndex;
+
+ /**
+ * Encoded record for pool task waits. Usages are always
+ * surrounded by volatile reads/writes
+ */
+ int nextWait;
/**
- * The last pool event waited for. Accessed only by pool in
- * callback methods invoked within this thread.
+ * Complement of poolIndex, offset by count of entries of task
+ * waits. Accessed by ForkJoinPool to manage event waiters.
*/
- int lastEventCount;
+ volatile int eventCount;
+
+ /**
+ * Seed for random number generator for choosing steal victims.
+ * Uses Marsaglia xorshift. Must be initialized as nonzero.
+ */
+ int seed;
/**
- * Encoded index and event count of next event waiter. Accessed
- * only by ForkJoinPool for managing event waiters.
+ * Number of steals. Directly accessed (and reset) by pool when
+ * idle.
*/
- volatile long nextWaiter;
+ int stealCount;
+
+ /**
+ * True if this worker should or did terminate
+ */
+ volatile boolean terminate;
/**
- * Number of times this thread suspended as spare. Accessed only
- * by pool.
+ * Set to true before LockSupport.park; false on return
*/
- int spareCount;
+ volatile boolean parked;
/**
- * Encoded index and count of next spare waiter. Accessed only
- * by ForkJoinPool for managing spares.
+ * True if use local fifo, not default lifo, for local polling.
+ * Shadows value from ForkJoinPool.
*/
- volatile int nextSpare;
+ final boolean locallyFifo;
+
+ /**
+ * The task most recently stolen from another worker (or
+ * submission queue). All uses are surrounded by enough volatile
+ * reads/writes to maintain as non-volatile.
+ */
+ ForkJoinTask> currentSteal;
/**
* The task currently being joined, set only when actively trying
- * to help other stealers in helpJoinTask. Written only by this
- * thread, but read by others.
+ * to help other stealers in helpJoinTask. All uses are surrounded
+ * by enough volatile reads/writes to maintain as non-volatile.
*/
- private volatile ForkJoinTask> currentJoin;
-
- /**
- * The task most recently stolen from another worker (or
- * submission queue). Written only by this thread, but read by
- * others.
- */
- private volatile ForkJoinTask> currentSteal;
+ ForkJoinTask> currentJoin;
/**
* Creates a ForkJoinWorkerThread operating in the given pool.
@@ -334,24 +294,19 @@
* @throws NullPointerException if pool is null
*/
protected ForkJoinWorkerThread(ForkJoinPool pool) {
+ super(pool.nextWorkerName());
this.pool = pool;
- this.locallyFifo = pool.locallyFifo;
+ int k = pool.registerWorker(this);
+ poolIndex = k;
+ eventCount = ~k & SMASK; // clear wait count
+ locallyFifo = pool.locallyFifo;
+ Thread.UncaughtExceptionHandler ueh = pool.ueh;
+ if (ueh != null)
+ setUncaughtExceptionHandler(ueh);
setDaemon(true);
- // To avoid exposing construction details to subclasses,
- // remaining initialization is in start() and onStart()
}
- /**
- * Performs additional initialization and starts this thread.
- */
- final void start(int poolIndex, UncaughtExceptionHandler ueh) {
- this.poolIndex = poolIndex;
- if (ueh != null)
- setUncaughtExceptionHandler(ueh);
- start();
- }
-
- // Public/protected methods
+ // Public methods
/**
* Returns the pool hosting this thread.
@@ -375,6 +330,25 @@
return poolIndex;
}
+ // Randomization
+
+ /**
+ * Computes next value for random victim probes and backoffs.
+ * Scans don't require a very high quality generator, but also not
+ * a crummy one. Marsaglia xor-shift is cheap and works well
+ * enough. Note: This is manually inlined in FJP.scan() to avoid
+ * writes inside busy loops.
+ */
+ private int nextSeed() {
+ int r = seed;
+ r ^= r << 13;
+ r ^= r >>> 17;
+ r ^= r << 5;
+ return seed = r;
+ }
+
+ // Run State management
+
/**
* Initializes internal state after construction but before
* processing any tasks. If you override this method, you must
@@ -385,15 +359,9 @@
* processing tasks.
*/
protected void onStart() {
- int rs = seedGenerator.nextInt();
- seed = (rs == 0) ? 1 : rs; // seed must be nonzero
-
- // Allocate name string and arrays in this thread
- String pid = Integer.toString(pool.getPoolNumber());
- String wid = Integer.toString(poolIndex);
- setName("ForkJoinPool-" + pid + "-worker-" + wid);
-
queue = new ForkJoinTask>[INITIAL_QUEUE_CAPACITY];
+ int r = pool.workerSeedGenerator.nextInt();
+ seed = (r == 0)? 1 : r; // must be nonzero
}
/**
@@ -406,16 +374,9 @@
*/
protected void onTermination(Throwable exception) {
try {
- ForkJoinPool p = pool;
- if (active) {
- int a; // inline p.tryDecrementActiveCount
- active = false;
- do {} while (!UNSAFE.compareAndSwapInt
- (p, poolRunStateOffset, a = p.runState, a - 1));
- }
+ terminate = true;
cancelTasks();
- setTerminated();
- p.workerTerminated(this);
+ pool.deregisterWorker(this, exception);
} catch (Throwable ex) { // Shouldn't ever happen
if (exception == null) // but if so, at least rethrown
exception = ex;
@@ -434,7 +395,7 @@
Throwable exception = null;
try {
onStart();
- mainLoop();
+ pool.work(this);
} catch (Throwable ex) {
exception = ex;
} finally {
@@ -442,81 +403,6 @@
}
}
- // helpers for run()
-
- /**
- * Finds and executes tasks, and checks status while running.
- */
- private void mainLoop() {
- boolean ran = false; // true if ran a task on last step
- ForkJoinPool p = pool;
- for (;;) {
- p.preStep(this, ran);
- if (runState != 0)
- break;
- ran = tryExecSteal() || tryExecSubmission();
- }
- }
-
- /**
- * Tries to steal a task and execute it.
- *
- * @return true if ran a task
- */
- private boolean tryExecSteal() {
- ForkJoinTask> t;
- if ((t = scan()) != null) {
- t.quietlyExec();
- UNSAFE.putOrderedObject(this, currentStealOffset, null);
- if (sp != base)
- execLocalTasks();
- return true;
- }
- return false;
- }
-
- /**
- * If a submission exists, try to activate and run it.
- *
- * @return true if ran a task
- */
- private boolean tryExecSubmission() {
- ForkJoinPool p = pool;
- // This loop is needed in case attempt to activate fails, in
- // which case we only retry if there still appears to be a
- // submission.
- while (p.hasQueuedSubmissions()) {
- ForkJoinTask> t; int a;
- if (active || // inline p.tryIncrementActiveCount
- (active = UNSAFE.compareAndSwapInt(p, poolRunStateOffset,
- a = p.runState, a + 1))) {
- if ((t = p.pollSubmission()) != null) {
- UNSAFE.putOrderedObject(this, currentStealOffset, t);
- t.quietlyExec();
- UNSAFE.putOrderedObject(this, currentStealOffset, null);
- if (sp != base)
- execLocalTasks();
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Runs local tasks until queue is empty or shut down. Call only
- * while active.
- */
- private void execLocalTasks() {
- while (runState == 0) {
- ForkJoinTask> t = locallyFifo ? locallyDeqTask() : popTask();
- if (t != null)
- t.quietlyExec();
- else if (sp == base)
- break;
- }
- }
-
/*
* Intrinsics-based atomic writes for queue slots. These are
* basically the same as methods in AtomicReferenceArray, but
@@ -528,10 +414,20 @@
* because they are protected by other volatile reads and are
* confirmed by CASes.
*
- * Most uses don't actually call these methods, but instead contain
- * inlined forms that enable more predictable optimization. We
- * don't define the version of write used in pushTask at all, but
- * instead inline there a store-fenced array slot write.
+ * Most uses don't actually call these methods, but instead
+ * contain inlined forms that enable more predictable
+ * optimization. We don't define the version of write used in
+ * pushTask at all, but instead inline there a store-fenced array
+ * slot write.
+ *
+ * Also in most methods, as a performance (not correctness) issue,
+ * we'd like to encourage compilers not to arbitrarily postpone
+ * setting queueTop after writing slot. Currently there is no
+ * intrinsic for arranging this, but using Unsafe putOrderedInt
+ * may be a preferable strategy on some compilers even though its
+ * main effect is a pre-, not post- fence. To simplify possible
+ * changes, the option is left in comments next to the associated
+ * assignments.
*/
/**
@@ -540,7 +436,7 @@
*/
private static final boolean casSlotNull(ForkJoinTask>[] q, int i,
ForkJoinTask> t) {
- return UNSAFE.compareAndSwapObject(q, (i << qShift) + qBase, t, null);
+ return UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null);
}
/**
@@ -550,7 +446,7 @@
*/
private static final void writeSlot(ForkJoinTask>[] q, int i,
ForkJoinTask> t) {
- UNSAFE.putObjectVolatile(q, (i << qShift) + qBase, t);
+ UNSAFE.putObjectVolatile(q, (i << ASHIFT) + ABASE, t);
}
// queue methods
@@ -561,14 +457,43 @@
* @param t the task. Caller must ensure non-null.
*/
final void pushTask(ForkJoinTask> t) {
- ForkJoinTask>[] q = queue;
- int mask = q.length - 1; // implicit assert q != null
- int s = sp++; // ok to increment sp before slot write
- UNSAFE.putOrderedObject(q, ((s & mask) << qShift) + qBase, t);
- if ((s -= base) == 0)
- pool.signalWork(); // was empty
- else if (s == mask)
- growQueue(); // is full
+ ForkJoinTask>[] q; int s, m;
+ if ((q = queue) != null) { // ignore if queue removed
+ long u = (((s = queueTop) & (m = q.length - 1)) << ASHIFT) + ABASE;
+ UNSAFE.putOrderedObject(q, u, t);
+ queueTop = s + 1; // or use putOrderedInt
+ if ((s -= queueBase) <= 2)
+ pool.signalWork();
+ else if (s == m)
+ growQueue();
+ }
+ }
+
+ /**
+ * Creates or doubles queue array. Transfers elements by
+ * emulating steals (deqs) from old array and placing, oldest
+ * first, into new array.
+ */
+ private void growQueue() {
+ ForkJoinTask>[] oldQ = queue;
+ int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY;
+ if (size > MAXIMUM_QUEUE_CAPACITY)
+ throw new RejectedExecutionException("Queue capacity exceeded");
+ if (size < INITIAL_QUEUE_CAPACITY)
+ size = INITIAL_QUEUE_CAPACITY;
+ ForkJoinTask>[] q = queue = new ForkJoinTask>[size];
+ int mask = size - 1;
+ int top = queueTop;
+ int oldMask;
+ if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) {
+ for (int b = queueBase; b != top; ++b) {
+ long u = ((b & oldMask) << ASHIFT) + ABASE;
+ Object x = UNSAFE.getObjectVolatile(oldQ, u);
+ if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null))
+ UNSAFE.putObjectVolatile
+ (q, ((b & mask) << ASHIFT) + ABASE, x);
+ }
+ }
}
/**
@@ -579,35 +504,34 @@
* @return a task, or null if none or contended
*/
final ForkJoinTask> deqTask() {
- ForkJoinTask> t;
- ForkJoinTask>[] q;
- int b, i;
- if (sp != (b = base) &&
+ ForkJoinTask> t; ForkJoinTask>[] q; int b, i;
+ if (queueTop != (b = queueBase) &&
(q = queue) != null && // must read q after b
- (t = q[i = (q.length - 1) & b]) != null && base == b &&
- UNSAFE.compareAndSwapObject(q, (i << qShift) + qBase, t, null)) {
- base = b + 1;
+ (i = (q.length - 1) & b) >= 0 &&
+ (t = q[i]) != null && queueBase == b &&
+ UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null)) {
+ queueBase = b + 1;
return t;
}
return null;
}
/**
- * Tries to take a task from the base of own queue. Assumes active
- * status. Called only by this thread.
+ * Tries to take a task from the base of own queue. Called only
+ * by this thread.
*
* @return a task, or null if none
*/
final ForkJoinTask> locallyDeqTask() {
+ ForkJoinTask> t; int m, b, i;
ForkJoinTask>[] q = queue;
- if (q != null) {
- ForkJoinTask> t;
- int b, i;
- while (sp != (b = base)) {
- if ((t = q[i = (q.length - 1) & b]) != null && base == b &&
- UNSAFE.compareAndSwapObject(q, (i << qShift) + qBase,
+ if (q != null && (m = q.length - 1) >= 0) {
+ while (queueTop != (b = queueBase)) {
+ if ((t = q[i = m & b]) != null &&
+ queueBase == b &&
+ UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE,
t, null)) {
- base = b + 1;
+ queueBase = b + 1;
return t;
}
}
@@ -616,35 +540,21 @@
}
/**
- * Returns a popped task, or null if empty. Assumes active status.
+ * Returns a popped task, or null if empty.
* Called only by this thread.
*/
private ForkJoinTask> popTask() {
+ int m;
ForkJoinTask>[] q = queue;
- if (q != null) {
- int s;
- while ((s = sp) != base) {
- int i = (q.length - 1) & --s;
- long u = (i << qShift) + qBase; // raw offset
+ if (q != null && (m = q.length - 1) >= 0) {
+ for (int s; (s = queueTop) != queueBase;) {
+ int i = m & --s;
+ long u = (i << ASHIFT) + ABASE; // raw offset
ForkJoinTask> t = q[i];
if (t == null) // lost to stealer
break;
if (UNSAFE.compareAndSwapObject(q, u, t, null)) {
- /*
- * Note: here and in related methods, as a
- * performance (not correctness) issue, we'd like
- * to encourage compiler not to arbitrarily
- * postpone setting sp after successful CAS.
- * Currently there is no intrinsic for arranging
- * this, but using Unsafe putOrderedInt may be a
- * preferable strategy on some compilers even
- * though its main effect is a pre-, not post-
- * fence. To simplify possible changes, the option
- * is left in comments next to the associated
- * assignments.
- */
- sp = s; // putOrderedInt may encourage more timely write
- // UNSAFE.putOrderedInt(this, spOffset, s);
+ queueTop = s; // or putOrderedInt
return t;
}
}
@@ -654,18 +564,17 @@
/**
* Specialized version of popTask to pop only if topmost element
- * is the given task. Called only by this thread while active.
+ * is the given task. Called only by this thread.
*
* @param t the task. Caller must ensure non-null.
*/
final boolean unpushTask(ForkJoinTask> t) {
+ ForkJoinTask>[] q;
int s;
- ForkJoinTask>[] q = queue;
- if ((s = sp) != base && q != null &&
+ if ((q = queue) != null && (s = queueTop) != queueBase &&
UNSAFE.compareAndSwapObject
- (q, (((q.length - 1) & --s) << qShift) + qBase, t, null)) {
- sp = s; // putOrderedInt may encourage more timely write
- // UNSAFE.putOrderedInt(this, spOffset, s);
+ (q, (((q.length - 1) & --s) << ASHIFT) + ABASE, t, null)) {
+ queueTop = s; // or putOrderedInt
return true;
}
return false;
@@ -675,222 +584,30 @@
* Returns next task, or null if empty or contended.
*/
final ForkJoinTask> peekTask() {
+ int m;
ForkJoinTask>[] q = queue;
- if (q == null)
+ if (q == null || (m = q.length - 1) < 0)
return null;
- int mask = q.length - 1;
- int i = locallyFifo ? base : (sp - 1);
- return q[i & mask];
+ int i = locallyFifo ? queueBase : (queueTop - 1);
+ return q[i & m];
}
- /**
- * Doubles queue array size. Transfers elements by emulating
- * steals (deqs) from old array and placing, oldest first, into
- * new array.
- */
- private void growQueue() {
- ForkJoinTask>[] oldQ = queue;
- int oldSize = oldQ.length;
- int newSize = oldSize << 1;
- if (newSize > MAXIMUM_QUEUE_CAPACITY)
- throw new RejectedExecutionException("Queue capacity exceeded");
- ForkJoinTask>[] newQ = queue = new ForkJoinTask>[newSize];
-
- int b = base;
- int bf = b + oldSize;
- int oldMask = oldSize - 1;
- int newMask = newSize - 1;
- do {
- int oldIndex = b & oldMask;
- ForkJoinTask> t = oldQ[oldIndex];
- if (t != null && !casSlotNull(oldQ, oldIndex, t))
- t = null;
- writeSlot(newQ, b & newMask, t);
- } while (++b != bf);
- pool.signalWork();
- }
-
- /**
- * Computes next value for random victim probe in scan(). Scans
- * don't require a very high quality generator, but also not a
- * crummy one. Marsaglia xor-shift is cheap and works well enough.
- * Note: This is manually inlined in scan().
- */
- private static final int xorShift(int r) {
- r ^= r << 13;
- r ^= r >>> 17;
- return r ^ (r << 5);
- }
+ // Support methods for ForkJoinPool
/**
- * Tries to steal a task from another worker. Starts at a random
- * index of workers array, and probes workers until finding one
- * with non-empty queue or finding that all are empty. It
- * randomly selects the first n probes. If these are empty, it
- * resorts to a circular sweep, which is necessary to accurately
- * set active status. (The circular sweep uses steps of
- * approximately half the array size plus 1, to avoid bias
- * stemming from leftmost packing of the array in ForkJoinPool.)
- *
- * This method must be both fast and quiet -- usually avoiding
- * memory accesses that could disrupt cache sharing etc other than
- * those needed to check for and take tasks (or to activate if not
- * already active). This accounts for, among other things,
- * updating random seed in place without storing it until exit.
- *
- * @return a task, or null if none found
+ * Runs the given task, plus any local tasks until queue is empty
*/
- private ForkJoinTask> scan() {
- ForkJoinPool p = pool;
- ForkJoinWorkerThread[] ws; // worker array
- int n; // upper bound of #workers
- if ((ws = p.workers) != null && (n = ws.length) > 1) {
- boolean canSteal = active; // shadow active status
- int r = seed; // extract seed once
- int mask = n - 1;
- int j = -n; // loop counter
- int k = r; // worker index, random if j < 0
- for (;;) {
- ForkJoinWorkerThread v = ws[k & mask];
- r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // inline xorshift
- ForkJoinTask>[] q; ForkJoinTask> t; int b, a;
- if (v != null && (b = v.base) != v.sp &&
- (q = v.queue) != null) {
- int i = (q.length - 1) & b;
- long u = (i << qShift) + qBase; // raw offset
- int pid = poolIndex;
- if ((t = q[i]) != null) {
- if (!canSteal && // inline p.tryIncrementActiveCount
- UNSAFE.compareAndSwapInt(p, poolRunStateOffset,
- a = p.runState, a + 1))
- canSteal = active = true;
- if (canSteal && v.base == b++ &&
- UNSAFE.compareAndSwapObject(q, u, t, null)) {
- v.base = b;
- v.stealHint = pid;
- UNSAFE.putOrderedObject(this,
- currentStealOffset, t);
- seed = r;
- ++stealCount;
- return t;
- }
- }
- j = -n;
- k = r; // restart on contention
- }
- else if (++j <= 0)
- k = r;
- else if (j <= n)
- k += (n >>> 1) | 1;
- else
- break;
- }
- }
- return null;
- }
-
- // Run State management
-
- // status check methods used mainly by ForkJoinPool
- final boolean isRunning() { return runState == 0; }
- final boolean isTerminated() { return (runState & TERMINATED) != 0; }
- final boolean isSuspended() { return (runState & SUSPENDED) != 0; }
- final boolean isTrimmed() { return (runState & TRIMMED) != 0; }
-
- final boolean isTerminating() {
- if ((runState & TERMINATING) != 0)
- return true;
- if (pool.isAtLeastTerminating()) { // propagate pool state
- shutdown();
- return true;
+ final void execTask(ForkJoinTask> t) {
+ currentSteal = t;
+ for (;;) {
+ if (t != null)
+ t.doExec();
+ if (queueTop == queueBase)
+ break;
+ t = locallyFifo ? locallyDeqTask() : popTask();
}
- return false;
- }
-
- /**
- * Sets state to TERMINATING. Does NOT unpark or interrupt
- * to wake up if currently blocked. Callers must do so if desired.
- */
- final void shutdown() {
- for (;;) {
- int s = runState;
- if ((s & (TERMINATING|TERMINATED)) != 0)
- break;
- if ((s & SUSPENDED) != 0) { // kill and wakeup if suspended
- if (UNSAFE.compareAndSwapInt(this, runStateOffset, s,
- (s & ~SUSPENDED) |
- (TRIMMED|TERMINATING)))
- break;
- }
- else if (UNSAFE.compareAndSwapInt(this, runStateOffset, s,
- s | TERMINATING))
- break;
- }
- }
-
- /**
- * Sets state to TERMINATED. Called only by onTermination().
- */
- private void setTerminated() {
- int s;
- do {} while (!UNSAFE.compareAndSwapInt(this, runStateOffset,
- s = runState,
- s | (TERMINATING|TERMINATED)));
- }
-
- /**
- * If suspended, tries to set status to unsuspended.
- * Does NOT wake up if blocked.
- *
- * @return true if successful
- */
- final boolean tryUnsuspend() {
- int s;
- while (((s = runState) & SUSPENDED) != 0) {
- if (UNSAFE.compareAndSwapInt(this, runStateOffset, s,
- s & ~SUSPENDED))
- return true;
- }
- return false;
- }
-
- /**
- * Sets suspended status and blocks as spare until resumed
- * or shutdown.
- */
- final void suspendAsSpare() {
- for (;;) { // set suspended unless terminating
- int s = runState;
- if ((s & TERMINATING) != 0) { // must kill
- if (UNSAFE.compareAndSwapInt(this, runStateOffset, s,
- s | (TRIMMED | TERMINATING)))
- return;
- }
- else if (UNSAFE.compareAndSwapInt(this, runStateOffset, s,
- s | SUSPENDED))
- break;
- }
- ForkJoinPool p = pool;
- p.pushSpare(this);
- while ((runState & SUSPENDED) != 0) {
- if (p.tryAccumulateStealCount(this)) {
- interrupted(); // clear/ignore interrupts
- if ((runState & SUSPENDED) == 0)
- break;
- LockSupport.park(this);
- }
- }
- }
-
- // Misc support methods for ForkJoinPool
-
- /**
- * Returns an estimate of the number of tasks in the queue. Also
- * used by ForkJoinTask.
- */
- final int getQueueSize() {
- int n; // external calls must read base first
- return (n = -base + sp) <= 0 ? 0 : n;
+ ++stealCount;
+ currentSteal = null;
}
/**
@@ -899,17 +616,12 @@
*/
final void cancelTasks() {
ForkJoinTask> cj = currentJoin; // try to cancel ongoing tasks
- if (cj != null && cj.status >= 0) {
+ if (cj != null && cj.status >= 0)
cj.cancelIgnoringExceptions();
- try {
- this.interrupt(); // awaken wait
- } catch (SecurityException ignore) {
- }
- }
ForkJoinTask> cs = currentSteal;
if (cs != null && cs.status >= 0)
cs.cancelIgnoringExceptions();
- while (base != sp) {
+ while (queueBase != queueTop) {
ForkJoinTask> t = deqTask();
if (t != null)
t.cancelIgnoringExceptions();
@@ -923,7 +635,7 @@
*/
final int drainTasksTo(Collection super ForkJoinTask>> c) {
int n = 0;
- while (base != sp) {
+ while (queueBase != queueTop) {
ForkJoinTask> t = deqTask();
if (t != null) {
c.add(t);
@@ -936,20 +648,19 @@
// Support methods for ForkJoinTask
/**
+ * Returns an estimate of the number of tasks in the queue.
+ */
+ final int getQueueSize() {
+ return queueTop - queueBase;
+ }
+
+ /**
* Gets and removes a local task.
*
* @return a task, if available
*/
final ForkJoinTask> pollLocalTask() {
- ForkJoinPool p = pool;
- while (sp != base) {
- int a; // inline p.tryIncrementActiveCount
- if (active ||
- (active = UNSAFE.compareAndSwapInt(p, poolRunStateOffset,
- a = p.runState, a + 1)))
- return locallyFifo ? locallyDeqTask() : popTask();
- }
- return null;
+ return locallyFifo ? locallyDeqTask() : popTask();
}
/**
@@ -958,172 +669,205 @@
* @return a task, if available
*/
final ForkJoinTask> pollTask() {
+ ForkJoinWorkerThread[] ws;
ForkJoinTask> t = pollLocalTask();
- if (t == null) {
- t = scan();
- // cannot retain/track/help steal
- UNSAFE.putOrderedObject(this, currentStealOffset, null);
+ if (t != null || (ws = pool.workers) == null)
+ return t;
+ int n = ws.length; // cheap version of FJP.scan
+ int steps = n << 1;
+ int r = nextSeed();
+ int i = 0;
+ while (i < steps) {
+ ForkJoinWorkerThread w = ws[(i++ + r) & (n - 1)];
+ if (w != null && w.queueBase != w.queueTop && w.queue != null) {
+ if ((t = w.deqTask()) != null)
+ return t;
+ i = 0;
+ }
}
- return t;
+ return null;
}
/**
- * Possibly runs some tasks and/or blocks, until task is done.
+ * The maximum stolen->joining link depth allowed in helpJoinTask,
+ * as well as the maximum number of retries (allowing on average
+ * one staleness retry per level) per attempt to instead try
+ * compensation. Depths for legitimate chains are unbounded, but
+ * we use a fixed constant to avoid (otherwise unchecked) cycles
+ * and bound staleness of traversal parameters at the expense of
+ * sometimes blocking when we could be helping.
+ */
+ private static final int MAX_HELP = 16;
+
+ /**
+ * Possibly runs some tasks and/or blocks, until joinMe is done.
*
* @param joinMe the task to join
- * @param timed true if use timed wait
- * @param nanos wait time if timed
+ * @return completion status on exit
*/
- final void joinTask(ForkJoinTask> joinMe, boolean timed, long nanos) {
- // currentJoin only written by this thread; only need ordered store
+ final int joinTask(ForkJoinTask> joinMe) {
ForkJoinTask> prevJoin = currentJoin;
- UNSAFE.putOrderedObject(this, currentJoinOffset, joinMe);
- pool.awaitJoin(joinMe, this, timed, nanos);
- UNSAFE.putOrderedObject(this, currentJoinOffset, prevJoin);
+ currentJoin = joinMe;
+ for (int s, retries = MAX_HELP;;) {
+ if ((s = joinMe.status) < 0) {
+ currentJoin = prevJoin;
+ return s;
+ }
+ if (retries > 0) {
+ if (queueTop != queueBase) {
+ if (!localHelpJoinTask(joinMe))
+ retries = 0; // cannot help
+ }
+ else if (retries == MAX_HELP >>> 1) {
+ --retries; // check uncommon case
+ if (tryDeqAndExec(joinMe) >= 0)
+ Thread.yield(); // for politeness
+ }
+ else
+ retries = helpJoinTask(joinMe)? MAX_HELP : retries - 1;
+ }
+ else {
+ retries = MAX_HELP; // restart if not done
+ pool.tryAwaitJoin(joinMe);
+ }
+ }
+ }
+
+ /**
+ * If present, pops and executes the given task, or any other
+ * cancelled task
+ *
+ * @return false if any other non-cancelled task exists in local queue
+ */
+ private boolean localHelpJoinTask(ForkJoinTask> joinMe) {
+ int s, i; ForkJoinTask>[] q; ForkJoinTask> t;
+ if ((s = queueTop) != queueBase && (q = queue) != null &&
+ (i = (q.length - 1) & --s) >= 0 &&
+ (t = q[i]) != null) {
+ if (t != joinMe && t.status >= 0)
+ return false;
+ if (UNSAFE.compareAndSwapObject
+ (q, (i << ASHIFT) + ABASE, t, null)) {
+ queueTop = s; // or putOrderedInt
+ t.doExec();
+ }
+ }
+ return true;
}
/**
- * Tries to locate and help perform tasks for a stealer of the
- * given task, or in turn one of its stealers. Traces
+ * Tries to locate and execute tasks for a stealer of the given
+ * task, or in turn one of its stealers, Traces
* currentSteal->currentJoin links looking for a thread working on
* a descendant of the given task and with a non-empty queue to
- * steal back and execute tasks from.
- *
- * The implementation is very branchy to cope with potential
- * inconsistencies or loops encountering chains that are stale,
- * unknown, or of length greater than MAX_HELP_DEPTH links. All
- * of these cases are dealt with by just returning back to the
- * caller, who is expected to retry if other join mechanisms also
- * don't work out.
+ * steal back and execute tasks from. The implementation is very
+ * branchy to cope with potential inconsistencies or loops
+ * encountering chains that are stale, unknown, or of length
+ * greater than MAX_HELP links. All of these cases are dealt with
+ * by just retrying by caller.
*
* @param joinMe the task to join
- * @param running if false, then must update pool count upon
- * running a task
- * @return value of running on exit
+ * @param canSteal true if local queue is empty
+ * @return true if ran a task
*/
- final boolean helpJoinTask(ForkJoinTask> joinMe, boolean running) {
- /*
- * Initial checks to (1) abort if terminating; (2) clean out
- * old cancelled tasks from local queue; (3) if joinMe is next
- * task, run it; (4) omit scan if local queue nonempty (since
- * it may contain non-descendents of joinMe).
- */
- ForkJoinPool p = pool;
- for (;;) {
- ForkJoinTask>[] q;
- int s;
- if (joinMe.status < 0)
- return running;
- else if ((runState & TERMINATING) != 0) {
- joinMe.cancelIgnoringExceptions();
- return running;
+ private boolean helpJoinTask(ForkJoinTask> joinMe) {
+ boolean helped = false;
+ int m = pool.scanGuard & SMASK;
+ ForkJoinWorkerThread[] ws = pool.workers;
+ if (ws != null && ws.length > m && joinMe.status >= 0) {
+ int levels = MAX_HELP; // remaining chain length
+ ForkJoinTask> task = joinMe; // base of chain
+ outer:for (ForkJoinWorkerThread thread = this;;) {
+ // Try to find v, the stealer of task, by first using hint
+ ForkJoinWorkerThread v = ws[thread.stealHint & m];
+ if (v == null || v.currentSteal != task) {
+ for (int j = 0; ;) { // search array
+ if ((v = ws[j]) != null && v.currentSteal == task) {
+ thread.stealHint = j;
+ break; // save hint for next time
+ }
+ if (++j > m)
+ break outer; // can't find stealer
+ }
+ }
+ // Try to help v, using specialized form of deqTask
+ for (;;) {
+ ForkJoinTask>[] q; int b, i;
+ if (joinMe.status < 0)
+ break outer;
+ if ((b = v.queueBase) == v.queueTop ||
+ (q = v.queue) == null ||
+ (i = (q.length-1) & b) < 0)
+ break; // empty
+ long u = (i << ASHIFT) + ABASE;
+ ForkJoinTask> t = q[i];
+ if (task.status < 0)
+ break outer; // stale
+ if (t != null && v.queueBase == b &&
+ UNSAFE.compareAndSwapObject(q, u, t, null)) {
+ v.queueBase = b + 1;
+ v.stealHint = poolIndex;
+ ForkJoinTask> ps = currentSteal;
+ currentSteal = t;
+ t.doExec();
+ currentSteal = ps;
+ helped = true;
+ }
+ }
+ // Try to descend to find v's stealer
+ ForkJoinTask> next = v.currentJoin;
+ if (--levels > 0 && task.status >= 0 &&
+ next != null && next != task) {
+ task = next;
+ thread = v;
+ }
+ else
+ break; // max levels, stale, dead-end, or cyclic
}
- else if ((s = sp) == base || (q = queue) == null)
- break; // queue empty
- else {
- int i = (q.length - 1) & --s;
- long u = (i << qShift) + qBase; // raw offset
- ForkJoinTask> t = q[i];
- if (t == null)
- break; // lost to a stealer
- else if (t != joinMe && t.status >= 0)
- return running; // cannot safely help
- else if ((running ||
- (running = p.tryIncrementRunningCount())) &&
- UNSAFE.compareAndSwapObject(q, u, t, null)) {
- sp = s; // putOrderedInt may encourage more timely write
- // UNSAFE.putOrderedInt(this, spOffset, s);
- t.quietlyExec();
+ }
+ return helped;
+ }
+
+ /**
+ * Performs an uncommon case for joinTask: If task t is at base of
+ * some workers queue, steals and executes it.
+ *
+ * @param t the task
+ * @return t's status
+ */
+ private int tryDeqAndExec(ForkJoinTask> t) {
+ int m = pool.scanGuard & SMASK;
+ ForkJoinWorkerThread[] ws = pool.workers;
+ if (ws != null && ws.length > m && t.status >= 0) {
+ for (int j = 0; j <= m; ++j) {
+ ForkJoinTask>[] q; int b, i;
+ ForkJoinWorkerThread v = ws[j];
+ if (v != null &&
+ (b = v.queueBase) != v.queueTop &&
+ (q = v.queue) != null &&
+ (i = (q.length - 1) & b) >= 0 &&
+ q[i] == t) {
+ long u = (i << ASHIFT) + ABASE;
+ if (v.queueBase == b &&
+ UNSAFE.compareAndSwapObject(q, u, t, null)) {
+ v.queueBase = b + 1;
+ v.stealHint = poolIndex;
+ ForkJoinTask> ps = currentSteal;
+ currentSteal = t;
+ t.doExec();
+ currentSteal = ps;
+ }
+ break;
}
}
}
-
- int n; // worker array size
- ForkJoinWorkerThread[] ws = p.workers;
- if (ws != null && (n = ws.length) > 1) { // need at least 2 workers
- ForkJoinTask> task = joinMe; // base of chain
- ForkJoinWorkerThread thread = this; // thread with stolen task
-
- outer:for (int d = 0; d < MAX_HELP_DEPTH; ++d) { // chain length
- // Try to find v, the stealer of task, by first using hint
- ForkJoinWorkerThread v = ws[thread.stealHint & (n - 1)];
- if (v == null || v.currentSteal != task) {
- for (int j = 0; ; ++j) { // search array
- if (j < n) {
- ForkJoinTask> vs;
- if ((v = ws[j]) != null &&
- (vs = v.currentSteal) != null) {
- if (joinMe.status < 0)
- break outer;
- if (vs == task) {
- if (task.status < 0)
- break outer; // stale
- thread.stealHint = j;
- break; // save hint for next time
- }
- }
- }
- else
- break outer; // no stealer
- }
- }
-
- // Try to help v, using specialized form of deqTask
- for (;;) {
- if (joinMe.status < 0)
- break outer;
- int b = v.base;
- ForkJoinTask>[] q = v.queue;
- if (b == v.sp || q == null)
- break; // empty
- int i = (q.length - 1) & b;
- long u = (i << qShift) + qBase;
- ForkJoinTask> t = q[i];
- if (task.status < 0)
- break outer; // stale
- if (t != null &&
- (running ||
- (running = p.tryIncrementRunningCount())) &&
- v.base == b++ &&
- UNSAFE.compareAndSwapObject(q, u, t, null)) {
- if (t != joinMe && joinMe.status < 0) {
- UNSAFE.putObjectVolatile(q, u, t);
- break outer; // joinMe cancelled; back out
- }
- v.base = b;
- if (t.status >= 0) {
- ForkJoinTask> ps = currentSteal;
- int pid = poolIndex;
- v.stealHint = pid;
- UNSAFE.putOrderedObject(this,
- currentStealOffset, t);
- t.quietlyExec();
- UNSAFE.putOrderedObject(this,
- currentStealOffset, ps);
- }
- }
- else if ((runState & TERMINATING) != 0) {
- joinMe.cancelIgnoringExceptions();
- break outer;
- }
- }
-
- // Try to descend to find v's stealer
- ForkJoinTask> next = v.currentJoin;
- if (task.status < 0 || next == null || next == task ||
- joinMe.status < 0)
- break; // done, stale, dead-end, or cyclic
- task = next;
- thread = v;
- }
- }
- return running;
+ return t.status;
}
/**
- * Implements ForkJoinTask.getSurplusQueuedTaskCount().
- * Returns an estimate of the number of tasks, offset by a
- * function of number of idle workers.
+ * Implements ForkJoinTask.getSurplusQueuedTaskCount(). Returns
+ * an estimate of the number of tasks, offset by a function of
+ * number of idle workers.
*
* This method provides a cheap heuristic guide for task
* partitioning when programmers, frameworks, tools, or languages
@@ -1159,82 +903,96 @@
* When all threads are active, it is on average OK to estimate
* surplus strictly locally. In steady-state, if one thread is
* maintaining say 2 surplus tasks, then so are others. So we can
- * just use estimated queue length (although note that (sp - base)
- * can be an overestimate because of stealers lagging increments
- * of base). However, this strategy alone leads to serious
- * mis-estimates in some non-steady-state conditions (ramp-up,
- * ramp-down, other stalls). We can detect many of these by
- * further considering the number of "idle" threads, that are
+ * just use estimated queue length (although note that (queueTop -
+ * queueBase) can be an overestimate because of stealers lagging
+ * increments of queueBase). However, this strategy alone leads
+ * to serious mis-estimates in some non-steady-state conditions
+ * (ramp-up, ramp-down, other stalls). We can detect many of these
+ * by further considering the number of "idle" threads, that are
* known to have zero queued tasks, so compensate by a factor of
* (#idle/#active) threads.
*/
final int getEstimatedSurplusTaskCount() {
- return sp - base - pool.idlePerActive();
+ return queueTop - queueBase - pool.idlePerActive();
}
/**
- * Runs tasks until {@code pool.isQuiescent()}.
+ * Runs tasks until {@code pool.isQuiescent()}. We piggyback on
+ * pool's active count ctl maintenance, but rather than blocking
+ * when tasks cannot be found, we rescan until all others cannot
+ * find tasks either. The bracketing by pool quiescerCounts
+ * updates suppresses pool auto-shutdown mechanics that could
+ * otherwise prematurely terminate the pool because all threads
+ * appear to be inactive.
*/
final void helpQuiescePool() {
+ boolean active = true;
ForkJoinTask> ps = currentSteal; // to restore below
+ ForkJoinPool p = pool;
+ p.addQuiescerCount(1);
for (;;) {
- ForkJoinTask> t = pollLocalTask();
- if (t != null || (t = scan()) != null)
- t.quietlyExec();
+ ForkJoinWorkerThread[] ws = p.workers;
+ ForkJoinWorkerThread v = null;
+ int n;
+ if (queueTop != queueBase)
+ v = this;
+ else if (ws != null && (n = ws.length) > 1) {
+ ForkJoinWorkerThread w;
+ int r = nextSeed(); // cheap version of FJP.scan
+ int steps = n << 1;
+ for (int i = 0; i < steps; ++i) {
+ if ((w = ws[(i + r) & (n - 1)]) != null &&
+ w.queueBase != w.queueTop) {
+ v = w;
+ break;
+ }
+ }
+ }
+ if (v != null) {
+ ForkJoinTask> t;
+ if (!active) {
+ active = true;
+ p.addActiveCount(1);
+ }
+ if ((t = (v != this) ? v.deqTask() :
+ locallyFifo? locallyDeqTask() : popTask()) != null) {
+ currentSteal = t;
+ t.doExec();
+ currentSteal = ps;
+ }
+ }
else {
- ForkJoinPool p = pool;
- int a; // to inline CASes
if (active) {
- if (!UNSAFE.compareAndSwapInt
- (p, poolRunStateOffset, a = p.runState, a - 1))
- continue; // retry later
- active = false; // inactivate
- UNSAFE.putOrderedObject(this, currentStealOffset, ps);
+ active = false;
+ p.addActiveCount(-1);
}
if (p.isQuiescent()) {
- active = true; // re-activate
- do {} while (!UNSAFE.compareAndSwapInt
- (p, poolRunStateOffset, a = p.runState, a+1));
- return;
+ p.addActiveCount(1);
+ p.addQuiescerCount(-1);
+ break;
}
}
}
}
// Unsafe mechanics
-
- private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
- private static final long spOffset =
- objectFieldOffset("sp", ForkJoinWorkerThread.class);
- private static final long runStateOffset =
- objectFieldOffset("runState", ForkJoinWorkerThread.class);
- private static final long currentJoinOffset =
- objectFieldOffset("currentJoin", ForkJoinWorkerThread.class);
- private static final long currentStealOffset =
- objectFieldOffset("currentSteal", ForkJoinWorkerThread.class);
- private static final long qBase =
- UNSAFE.arrayBaseOffset(ForkJoinTask[].class);
- private static final long poolRunStateOffset = // to inline CAS
- objectFieldOffset("runState", ForkJoinPool.class);
-
- private static final int qShift;
+ private static final sun.misc.Unsafe UNSAFE;
+ private static final long ABASE;
+ private static final int ASHIFT;
static {
- int s = UNSAFE.arrayIndexScale(ForkJoinTask[].class);
+ int s;
+ try {
+ UNSAFE = sun.misc.Unsafe.getUnsafe();
+ Class a = ForkJoinTask[].class;
+ ABASE = UNSAFE.arrayBaseOffset(a);
+ s = UNSAFE.arrayIndexScale(a);
+ } catch (Exception e) {
+ throw new Error(e);
+ }
if ((s & (s-1)) != 0)
throw new Error("data type scale not a power of two");
- qShift = 31 - Integer.numberOfLeadingZeros(s);
- MAXIMUM_QUEUE_CAPACITY = 1 << (31 - qShift);
+ ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
}
- private static long objectFieldOffset(String field, Class> klazz) {
- try {
- return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
- } catch (NoSuchFieldException e) {
- // Convert Exception to corresponding Error
- NoSuchFieldError error = new NoSuchFieldError(field);
- error.initCause(e);
- throw error;
- }
- }
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/javax/swing/JOptionPane.java
--- a/jdk/src/share/classes/javax/swing/JOptionPane.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/JOptionPane.java Wed Jul 05 17:39:17 2017 +0200
@@ -987,11 +987,33 @@
}
dialog.pack();
dialog.setLocationRelativeTo(parentComponent);
+
+ final PropertyChangeListener listener = new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ // Let the defaultCloseOperation handle the closing
+ // if the user closed the window without selecting a button
+ // (newValue = null in that case). Otherwise, close the dialog.
+ if (dialog.isVisible() && event.getSource() == JOptionPane.this &&
+ (event.getPropertyName().equals(VALUE_PROPERTY) ||
+ event.getPropertyName().equals(INPUT_VALUE_PROPERTY)) &&
+ event.getNewValue() != null &&
+ event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {
+ dialog.setVisible(false);
+ }
+ }
+ };
+
WindowAdapter adapter = new WindowAdapter() {
private boolean gotFocus = false;
public void windowClosing(WindowEvent we) {
setValue(null);
}
+
+ public void windowClosed(WindowEvent e) {
+ removePropertyChangeListener(listener);
+ dialog.getContentPane().removeAll();
+ }
+
public void windowGainedFocus(WindowEvent we) {
// Once window gets focus, set initial focus
if (!gotFocus) {
@@ -1008,20 +1030,8 @@
setValue(JOptionPane.UNINITIALIZED_VALUE);
}
});
- addPropertyChangeListener(new PropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent event) {
- // Let the defaultCloseOperation handle the closing
- // if the user closed the window without selecting a button
- // (newValue = null in that case). Otherwise, close the dialog.
- if (dialog.isVisible() && event.getSource() == JOptionPane.this &&
- (event.getPropertyName().equals(VALUE_PROPERTY) ||
- event.getPropertyName().equals(INPUT_VALUE_PROPERTY)) &&
- event.getNewValue() != null &&
- event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {
- dialog.setVisible(false);
- }
- }
- });
+
+ addPropertyChangeListener(listener);
}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/javax/swing/Timer.java
--- a/jdk/src/share/classes/javax/swing/Timer.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/Timer.java Wed Jul 05 17:39:17 2017 +0200
@@ -35,6 +35,10 @@
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
+import java.io.*;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import javax.swing.event.EventListenerList;
@@ -208,6 +212,22 @@
}
}
+ /*
+ * The timer's AccessControlContext.
+ */
+ private transient volatile AccessControlContext acc =
+ AccessController.getContext();
+
+ /**
+ * Returns the acc this timer was constructed with.
+ */
+ final AccessControlContext getAccessControlContext() {
+ if (acc == null) {
+ throw new SecurityException(
+ "Timer is missing AccessControlContext");
+ }
+ return acc;
+ }
/**
* DoPostEvent is a runnable class that fires actionEvents to
@@ -587,8 +607,13 @@
void post() {
- if (notify.compareAndSet(false, true) || !coalesce) {
- SwingUtilities.invokeLater(doPostEvent);
+ if (notify.compareAndSet(false, true) || !coalesce) {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Void run() {
+ SwingUtilities.invokeLater(doPostEvent);
+ return null;
+ }
+ }, getAccessControlContext());
}
}
@@ -596,6 +621,13 @@
return lock;
}
+ private void readObject(ObjectInputStream in)
+ throws ClassNotFoundException, IOException
+ {
+ this.acc = AccessController.getContext();
+ in.defaultReadObject();
+ }
+
/*
* We have to use readResolve because we can not initialize final
* fields for deserialized object otherwise
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/javax/swing/TransferHandler.java
--- a/jdk/src/share/classes/javax/swing/TransferHandler.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/TransferHandler.java Wed Jul 05 17:39:17 2017 +0200
@@ -42,6 +42,16 @@
import sun.swing.*;
import sun.awt.SunToolkit;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.security.AccessControlContext;
+import java.security.ProtectionDomain;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaSecurityAccess;
+
+import sun.awt.AWTAccessor;
+
/**
* This class is used to handle the transfer of a Transferable
* to and from Swing components. The Transferable
is used to
@@ -1686,7 +1696,37 @@
return true;
}
- public void actionPerformed(ActionEvent e) {
+ private static final JavaSecurityAccess javaSecurityAccess =
+ SharedSecrets.getJavaSecurityAccess();
+
+ public void actionPerformed(final ActionEvent e) {
+ final Object src = e.getSource();
+
+ final PrivilegedAction action = new PrivilegedAction() {
+ public Void run() {
+ actionPerformedImpl(e);
+ return null;
+ }
+ };
+
+ final AccessControlContext stack = AccessController.getContext();
+ final AccessControlContext srcAcc = AWTAccessor.getComponentAccessor().getAccessControlContext((Component)src);
+ final AccessControlContext eventAcc = AWTAccessor.getAWTEventAccessor().getAccessControlContext(e);
+
+ if (srcAcc == null) {
+ javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc);
+ } else {
+ javaSecurityAccess.doIntersectionPrivilege(
+ new PrivilegedAction() {
+ public Void run() {
+ javaSecurityAccess.doIntersectionPrivilege(action, eventAcc);
+ return null;
+ }
+ }, stack, srcAcc);
+ }
+ }
+
+ private void actionPerformedImpl(ActionEvent e) {
Object src = e.getSource();
if (src instanceof JComponent) {
JComponent c = (JComponent) src;
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/Datatype.java
--- a/jdk/src/share/classes/org/relaxng/datatype/Datatype.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype;
-
-/**
- * Datatype object.
- *
- * This object has the following functionality:
- *
- *
- * functionality to identify a class of character sequences. This is
- * done through the isValid method.
- *
- * functionality to produce a "value object" from a character sequence and
- * context information.
- *
- * functionality to test the equality of two value objects.
- *
- *
- * This interface also defines the createStreamingValidator method,
- * which is intended to efficiently support the validation of
- * large character sequences.
- *
- * @author James Clark
- * @author Kohsuke KAWAGUCHI
- */
-public interface Datatype {
-
- /**
- * Checks if the specified 'literal' matches this Datatype
- * with respect to the current context.
- *
- * @param literal
- * the lexical representation to be checked.
- * @param context
- * If this datatype is context-dependent
- * (i.e. the {@link #isContextDependent} method returns true),
- * then the caller must provide a non-null valid context object.
- * Otherwise, the caller can pass null.
- *
- * @return
- * true if the 'literal' is a member of this Datatype;
- * false if it's not a member of this Datatype.
- */
- boolean isValid( String literal, ValidationContext context );
-
- /**
- * Similar to the isValid method but throws an exception with diagnosis
- * in case of errors.
- *
- *
- * If the specified 'literal' is a valid lexical representation for this
- * datatype, then this method must return without throwing any exception.
- * If not, the callee must throw an exception (with diagnosis message,
- * if possible.)
- *
- *
- * The application can use this method to provide detailed error message
- * to users. This method is kept separate from the isValid method to
- * achieve higher performance during normal validation.
- *
- * @exception DatatypeException
- * If the given literal is invalid, then this exception is thrown.
- * If the callee supports error diagnosis, then the exception should
- * contain a diagnosis message.
- */
- void checkValid( String literal, ValidationContext context )
- throws DatatypeException;
-
- /**
- * Creates an instance of a streaming validator for this type.
- *
- *
- * By using streaming validators instead of the isValid method,
- * the caller can avoid keeping the entire string, which is
- * sometimes quite big, in memory.
- *
- * @param context
- * If this datatype is context-dependent
- * (i.e. the {@link #isContextDependent} method returns true),
- * then the caller must provide a non-null valid context object.
- * Otherwise, the caller can pass null.
- * The callee may keep a reference to this context object
- * only while the returned streaming validator is being used.
- */
- DatatypeStreamingValidator createStreamingValidator( ValidationContext context );
-
- /**
- * Converts lexcial value and the current context to the corresponding
- * value object.
- *
- *
- * The caller cannot generally assume that the value object is
- * a meaningful Java object. For example, the caller cannot expect
- * this method to return java.lang.Number
type for
- * the "integer" type of XML Schema Part 2.
- *
- *
- * Also, the caller cannot assume that the equals method and
- * the hashCode method of the value object are consistent with
- * the semantics of the datatype. For that purpose, the sameValue
- * method and the valueHashCode method have to be used. Note that
- * this means you cannot use classes like
- * java.util.Hashtable
to store the value objects.
- *
- *
- * The returned value object should be used solely for the sameValue
- * and valueHashCode methods.
- *
- * @param context
- * If this datatype is context-dependent
- * (when the {@link #isContextDependent} method returns true),
- * then the caller must provide a non-null valid context object.
- * Otherwise, the caller can pass null.
- *
- * @return null
- * when the given lexical value is not a valid lexical
- * value for this type.
- */
- Object createValue( String literal, ValidationContext context );
-
- /**
- * Tests the equality of two value objects which were originally
- * created by the createValue method of this object.
- *
- * The behavior is undefined if objects not created by this type
- * are passed. It is the caller's responsibility to ensure that
- * value objects belong to this type.
- *
- * @return
- * true if two value objects are considered equal according to
- * the definition of this datatype; false if otherwise.
- */
- boolean sameValue( Object value1, Object value2 );
-
-
- /**
- * Computes the hash code for a value object,
- * which is consistent with the sameValue method.
- *
- * @return
- * hash code for the specified value object.
- */
- int valueHashCode( Object value );
-
-
-
-
- /**
- * Indicates that the datatype doesn't have ID/IDREF semantics.
- *
- * This value is one of the possible return values of the
- * {@link #getIdType} method.
- */
- public static final int ID_TYPE_NULL = 0;
-
- /**
- * Indicates that RELAX NG compatibility processors should
- * treat this datatype as having ID semantics.
- *
- * This value is one of the possible return values of the
- * {@link #getIdType} method.
- */
- public static final int ID_TYPE_ID = 1;
-
- /**
- * Indicates that RELAX NG compatibility processors should
- * treat this datatype as having IDREF semantics.
- *
- * This value is one of the possible return values of the
- * {@link #getIdType} method.
- */
- public static final int ID_TYPE_IDREF = 2;
-
- /**
- * Indicates that RELAX NG compatibility processors should
- * treat this datatype as having IDREFS semantics.
- *
- * This value is one of the possible return values of the
- * {@link #getIdType} method.
- */
- public static final int ID_TYPE_IDREFS = 3;
-
- /**
- * Checks if the ID/IDREF semantics is associated with this
- * datatype.
- *
- *
- * This method is introduced to support the RELAX NG DTD
- * compatibility spec. (Of course it's always free to use
- * this method for other purposes.)
- *
- *
- * If you are implementing a datatype library and have no idea about
- * the "RELAX NG DTD compatibility" thing, just return
- * ID_TYPE_NULL
is fine.
- *
- * @return
- * If this datatype doesn't have any ID/IDREF semantics,
- * it returns {@link #ID_TYPE_NULL}. If it has such a semantics
- * (for example, XSD:ID, XSD:IDREF and comp:ID type), then
- * it returns {@link #ID_TYPE_ID}, {@link #ID_TYPE_IDREF} or
- * {@link #ID_TYPE_IDREFS}.
- */
- public int getIdType();
-
-
- /**
- * Checks if this datatype may need a context object for
- * the validation.
- *
- *
- * The callee must return true even when the context
- * is not always necessary. (For example, the "QName" type
- * doesn't need a context object when validating unprefixed
- * string. But nonetheless QName must return true.)
- *
- *
- * XSD's string
and short
types
- * are examples of context-independent datatypes.
- * Its QName
and ENTITY
types
- * are examples of context-dependent datatypes.
- *
- *
- * When a datatype is context-independent, then
- * the {@link #isValid} method, the {@link #checkValid} method,
- * the {@link #createStreamingValidator} method and
- * the {@link #createValue} method can be called without
- * providing a context object.
- *
- * @return
- * true if this datatype is context-dependent
- * (it needs a context object sometimes);
- *
- * false if this datatype is context-in dependent
- * (it never needs a context object).
- */
- public boolean isContextDependent();
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/DatatypeBuilder.java
--- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeBuilder.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype;
-
-/**
- * Creates a user-defined type by adding parameters to
- * the pre-defined type.
- *
- * @author James Clark
- * @author Kohsuke KAWAGUCHI
- */
-public interface DatatypeBuilder {
-
- /**
- * Adds a new parameter.
- *
- * @param name
- * The name of the parameter to be added.
- * @param strValue
- * The raw value of the parameter. Caller may not normalize
- * this value because any white space is potentially significant.
- * @param context
- * The context information which can be used by the callee to
- * acquire additional information. This context object is
- * valid only during this method call. The callee may not
- * keep a reference to this object.
- * @exception DatatypeException
- * When the given parameter is inappropriate for some reason.
- * The callee is responsible to recover from this error.
- * That is, the object should behave as if no such error
- * was occured.
- */
- void addParameter( String name, String strValue, ValidationContext context )
- throws DatatypeException;
-
- /**
- * Derives a new Datatype from a Datatype by parameters that
- * were already set through the addParameter method.
- *
- * @exception DatatypeException
- * DatatypeException must be thrown if the derivation is
- * somehow invalid. For example, a required parameter is missing,
- * etc. The exception should contain a diagnosis message
- * if possible.
- */
- Datatype createDatatype() throws DatatypeException;
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/DatatypeException.java
--- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeException.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype;
-
-/**
- * Signals Datatype related exceptions.
- *
- * @author James Clark
- * @author Kohsuke KAWAGUCHI
- */
-public class DatatypeException extends Exception {
-
- public DatatypeException( int index, String msg ) {
- super(msg);
- this.index = index;
- }
- public DatatypeException( String msg ) {
- this(UNKNOWN,msg);
- }
- /**
- * A constructor for those datatype libraries which don't support any
- * diagnostic information at all.
- */
- public DatatypeException() {
- this(UNKNOWN,null);
- }
-
-
- private final int index;
-
- public static final int UNKNOWN = -1;
-
- /**
- * Gets the index of the content where the error occured.
- * UNKNOWN can be returned to indicate that no index information
- * is available.
- */
- public int getIndex() {
- return index;
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/DatatypeLibrary.java
--- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeLibrary.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype;
-
-/**
- * A Datatype library
- *
- * @author James Clark
- * @author Kohsuke KAWAGUCHI
- */
-public interface DatatypeLibrary {
-
- /**
- * Creates a new instance of DatatypeBuilder.
- *
- * The callee should throw a DatatypeException in case of an error.
- *
- * @param baseTypeLocalName
- * The local name of the base type.
- *
- * @return
- * A non-null valid datatype object.
- */
- DatatypeBuilder createDatatypeBuilder( String baseTypeLocalName )
- throws DatatypeException;
-
- /**
- * Gets or creates a pre-defined type.
- *
- * This is just a short-cut of
- * createDatatypeBuilder(typeLocalName).createDatatype();
- *
- * The callee should throw a DatatypeException in case of an error.
- *
- * @return
- * A non-null valid datatype object.
- */
- Datatype createDatatype( String typeLocalName ) throws DatatypeException;
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/DatatypeLibraryFactory.java
--- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeLibraryFactory.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype;
-
-/**
- * Factory class for the DatatypeLibrary class.
- *
- *
- * The datatype library should provide the implementation of
- * this interface if it wants to be found by the schema processors.
- * The implementor also have to place a file in your jar file.
- * See the reference datatype library implementation for detail.
- *
- * @author James Clark
- * @author Kohsuke KAWAGUCHI
- */
-public interface DatatypeLibraryFactory
-{
- /**
- * Creates a new instance of a DatatypeLibrary that supports
- * the specified namespace URI.
- *
- * @return
- * null
if the specified namespace URI is not
- * supported.
- */
- DatatypeLibrary createDatatypeLibrary( String namespaceURI );
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/DatatypeStreamingValidator.java
--- a/jdk/src/share/classes/org/relaxng/datatype/DatatypeStreamingValidator.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype;
-
-/**
- * Datatype streaming validator.
- *
- *
- * The streaming validator is an optional feature that is useful for
- * certain Datatypes. It allows the caller to incrementally provide
- * the literal.
- *
- * @author James Clark
- * @author Kohsuke KAWAGUCHI
- */
-public interface DatatypeStreamingValidator {
-
- /**
- * Passes an additional fragment of the literal.
- *
- *
- * The application can call this method several times, then call
- * the isValid method (or the checkValid method) to check the validity
- * of the accumulated characters.
- */
- void addCharacters( char[] buf, int start, int len );
-
- /**
- * Tells if the accumulated literal is valid with respect to
- * the underlying Datatype.
- *
- * @return
- * True if it is valid. False if otherwise.
- */
- boolean isValid();
-
- /**
- * Similar to the isValid method, but this method throws
- * Exception (with possibly diagnostic information), instead of
- * returning false.
- *
- * @exception DatatypeException
- * If the callee supports the diagnosis and the accumulated
- * literal is invalid, then this exception that possibly
- * contains diagnosis information is thrown.
- */
- void checkValid() throws DatatypeException;
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/ValidationContext.java
--- a/jdk/src/share/classes/org/relaxng/datatype/ValidationContext.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype;
-
-/**
- * An interface that must be implemented by caller to
- * provide context information that is necessary to
- * perform validation of some Datatypes.
- *
- * @author James Clark
- * @author Kohsuke KAWAGUCHI
- */
-public interface ValidationContext {
-
- /**
- * Resolves a namespace prefix to the corresponding namespace URI.
- *
- * This method is used for validating the QName type, for example.
- *
- *
- * If the prefix is "" (empty string), it indicates
- * an unprefixed value. The callee
- * should resolve it as for an unprefixed
- * element, rather than for an unprefixed attribute.
- *
- *
- * If the prefix is "xml", then the callee must resolve
- * this prefix into "http://www.w3.org/XML/1998/namespace",
- * as defined in the XML Namespaces Recommendation.
- *
- * @return
- * namespace URI of this prefix.
- * If the specified prefix is not declared,
- * the implementation must return null.
- */
- String resolveNamespacePrefix( String prefix );
-
- /**
- * Returns the base URI of the context. The null string may be returned
- * if no base URI is known.
- */
- String getBaseUri();
-
- /**
- * Checks if an unparsed entity is declared with the
- * specified name.
- *
- * @return
- * true
- * if the DTD has an unparsed entity declaration for
- * the specified name.
- * false
- * otherwise.
- */
- boolean isUnparsedEntity( String entityName );
-
- /**
- * Checks if a notation is declared with the
- * specified name.
- *
- * @return
- * true
- * if the DTD has a notation declaration for the specified name.
- * false
- * otherwise.
- */
- boolean isNotation( String notationName );
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java
--- a/jdk/src/share/classes/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-/**
- * Copyright (c) 2001, Thai Open Source Software Center Ltd
- * All rights reserved.
- *
- * 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 Thai Open Source Software Center Ltd nor
- * the names of its 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 THE REGENTS OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.relaxng.datatype.helpers;
-
-import org.relaxng.datatype.DatatypeLibraryFactory;
-import org.relaxng.datatype.DatatypeLibrary;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-import java.util.Vector;
-import java.io.Reader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-
-/**
- * Discovers the datatype library implementation from the classpath.
- *
- *
- * The call of the createDatatypeLibrary method finds an implementation
- * from a given datatype library URI at run-time.
- */
-public class DatatypeLibraryLoader implements DatatypeLibraryFactory {
- private final Service service = new Service(DatatypeLibraryFactory.class);
-
- public DatatypeLibrary createDatatypeLibrary(String uri) {
- for (Enumeration e = service.getProviders();
- e.hasMoreElements();) {
- DatatypeLibraryFactory factory
- = (DatatypeLibraryFactory)e.nextElement();
- DatatypeLibrary library = factory.createDatatypeLibrary(uri);
- if (library != null)
- return library;
- }
- return null;
- }
-
- private static class Service {
- private final Class serviceClass;
- private final Enumeration configFiles;
- private Enumeration classNames = null;
- private final Vector providers = new Vector();
- private Loader loader;
-
- private class ProviderEnumeration implements Enumeration {
- private int nextIndex = 0;
-
- public boolean hasMoreElements() {
- return nextIndex < providers.size() || moreProviders();
- }
-
- public Object nextElement() {
- try {
- return providers.elementAt(nextIndex++);
- }
- catch (ArrayIndexOutOfBoundsException e) {
- throw new NoSuchElementException();
- }
- }
- }
-
- private static class Singleton implements Enumeration {
- private Object obj;
- private Singleton(Object obj) {
- this.obj = obj;
- }
-
- public boolean hasMoreElements() {
- return obj != null;
- }
-
- public Object nextElement() {
- if (obj == null)
- throw new NoSuchElementException();
- Object tem = obj;
- obj = null;
- return tem;
- }
- }
-
- // JDK 1.1
- private static class Loader {
- Enumeration getResources(String resName) {
- ClassLoader cl = Loader.class.getClassLoader();
- URL url;
- if (cl == null)
- url = ClassLoader.getSystemResource(resName);
- else
- url = cl.getResource(resName);
- return new Singleton(url);
- }
-
- Class loadClass(String name) throws ClassNotFoundException {
- return Class.forName(name);
- }
- }
-
- // JDK 1.2+
- private static class Loader2 extends Loader {
- private ClassLoader cl;
-
- Loader2() {
- cl = Loader2.class.getClassLoader();
- // If the thread context class loader has the class loader
- // of this class as an ancestor, use the thread context class
- // loader. Otherwise, the thread context class loader
- // probably hasn't been set up properly, so don't use it.
- ClassLoader clt = Thread.currentThread().getContextClassLoader();
- for (ClassLoader tem = clt; tem != null; tem = tem.getParent())
- if (tem == cl) {
- cl = clt;
- break;
- }
- }
-
- Enumeration getResources(String resName) {
- try {
- return cl.getResources(resName);
-
- }
- catch (IOException e) {
- return new Singleton(null);
- }
- }
-
- Class loadClass(String name) throws ClassNotFoundException {
- return Class.forName(name, true, cl);
- }
- }
-
- public Service(Class cls) {
- try {
- loader = new Loader2();
- }
- catch (NoSuchMethodError e) {
- loader = new Loader();
- }
- serviceClass = cls;
- String resName = "META-INF/services/" + serviceClass.getName();
- configFiles = loader.getResources(resName);
- }
-
- public Enumeration getProviders() {
- return new ProviderEnumeration();
- }
-
- synchronized private boolean moreProviders() {
- for (;;) {
- while (classNames == null) {
- if (!configFiles.hasMoreElements())
- return false;
- classNames = parseConfigFile((URL)configFiles.nextElement());
- }
- while (classNames.hasMoreElements()) {
- String className = (String)classNames.nextElement();
- try {
- Class cls = loader.loadClass(className);
- Object obj = cls.newInstance();
- if (serviceClass.isInstance(obj)) {
- providers.addElement(obj);
- return true;
- }
- }
- catch (ClassNotFoundException e) { }
- catch (InstantiationException e) { }
- catch (IllegalAccessException e) { }
- catch (LinkageError e) { }
- }
- classNames = null;
- }
- }
-
- private static final int START = 0;
- private static final int IN_NAME = 1;
- private static final int IN_COMMENT = 2;
-
- private static Enumeration parseConfigFile(URL url) {
- try {
- InputStream in = url.openStream();
- Reader r;
- try {
- r = new InputStreamReader(in, "UTF-8");
- }
- catch (UnsupportedEncodingException e) {
- r = new InputStreamReader(in, "UTF8");
- }
- r = new BufferedReader(r);
- Vector tokens = new Vector();
- StringBuffer tokenBuf = new StringBuffer();
- int state = START;
- for (;;) {
- int n = r.read();
- if (n < 0)
- break;
- char c = (char)n;
- switch (c) {
- case '\r':
- case '\n':
- state = START;
- break;
- case ' ':
- case '\t':
- break;
- case '#':
- state = IN_COMMENT;
- break;
- default:
- if (state != IN_COMMENT) {
- state = IN_NAME;
- tokenBuf.append(c);
- }
- break;
- }
- if (tokenBuf.length() != 0 && state != IN_NAME) {
- tokens.addElement(tokenBuf.toString());
- tokenBuf.setLength(0);
- }
- }
- if (tokenBuf.length() != 0)
- tokens.addElement(tokenBuf.toString());
- return tokens.elements();
- }
- catch (IOException e) {
- return null;
- }
- }
- }
-
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java
--- a/jdk/src/share/classes/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype.helpers;
-
-import org.relaxng.datatype.*;
-
-/**
- * Dummy implementation of {@link DatatypeBuilder}.
- *
- * This implementation can be used for Datatypes which have no parameters.
- * Any attempt to add parameters will be rejected.
- *
- *
- * Typical usage would be:
- *
- * class MyDatatypeLibrary implements DatatypeLibrary {
- * ....
- * DatatypeBuilder createDatatypeBuilder( String typeName ) {
- * return new ParameterleessDatatypeBuilder(createDatatype(typeName));
- * }
- * ....
- * }
- *
- *
- * @author Kohsuke KAWAGUCHI
- */
-public final class ParameterlessDatatypeBuilder implements DatatypeBuilder {
-
- /** This type object is returned for the derive method. */
- private final Datatype baseType;
-
- public ParameterlessDatatypeBuilder( Datatype baseType ) {
- this.baseType = baseType;
- }
-
- public void addParameter( String name, String strValue, ValidationContext context )
- throws DatatypeException {
- throw new DatatypeException();
- }
-
- public Datatype createDatatype() throws DatatypeException {
- return baseType;
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/org/relaxng/datatype/helpers/StreamingValidatorImpl.java
--- a/jdk/src/share/classes/org/relaxng/datatype/helpers/StreamingValidatorImpl.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- */
-
-package org.relaxng.datatype.helpers;
-
-import org.relaxng.datatype.*;
-
-/**
- * Dummy implementation of {@link DatatypeStreamingValidator}.
- *
- *
- * This implementation can be used as a quick hack when the performance
- * of streaming validation is not important. And this implementation
- * also shows you how to implement the DatatypeStreamingValidator interface.
- *
- *
- * Typical usage would be:
- *
- * class MyDatatype implements Datatype {
- * ....
- * public DatatypeStreamingValidator createStreamingValidator( ValidationContext context ) {
- * return new StreamingValidatorImpl(this,context);
- * }
- * ....
- * }
- *
- *
- * @author Kohsuke KAWAGUCHI
- */
-public final class StreamingValidatorImpl implements DatatypeStreamingValidator {
-
- /** This buffer accumulates characters. */
- private final StringBuffer buffer = new StringBuffer();
-
- /** Datatype obejct that creates this streaming validator. */
- private final Datatype baseType;
-
- /** The current context. */
- private final ValidationContext context;
-
- public void addCharacters( char[] buf, int start, int len ) {
- // append characters to the current buffer.
- buffer.append(buf,start,len);
- }
-
- public boolean isValid() {
- return baseType.isValid(buffer.toString(),context);
- }
-
- public void checkValid() throws DatatypeException {
- baseType.checkValid(buffer.toString(),context);
- }
-
- public StreamingValidatorImpl( Datatype baseType, ValidationContext context ) {
- this.baseType = baseType;
- this.context = context;
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/overview-core.html
--- a/jdk/src/share/classes/overview-core.html Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/overview-core.html Wed Jul 05 17:39:17 2017 +0200
@@ -33,7 +33,7 @@
-This document is the API specification for version 6 of the Java™
+This document is the API specification for the Java™
Platform, Standard Edition.
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/awt/AWTAccessor.java
--- a/jdk/src/share/classes/sun/awt/AWTAccessor.java Sat Mar 26 00:11:34 2011 -0700
+++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java Wed Jul 05 17:39:17 2017 +0200
@@ -33,6 +33,9 @@
import sun.misc.Unsafe;
import java.awt.peer.ComponentPeer;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+
/**
* The AWTAccessor utility class.
* The main purpose of this class is to enable accessing
@@ -221,6 +224,13 @@
* Processes events occurring on this component.
*/
void processEvent(Component comp, AWTEvent e);
+
+
+ /*
+ * Returns the acc this component was constructed with.
+ */
+ AccessControlContext getAccessControlContext(Component comp);
+
}
/*
@@ -323,6 +333,13 @@
* Indicates whether this AWTEvent was generated by the system.
*/
boolean isSystemGenerated(AWTEvent ev);
+
+
+ /*
+ * Returns the acc this event was constructed with.
+ */
+ AccessControlContext getAccessControlContext(AWTEvent ev);
+
}
public interface InputEventAccessor {
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/Access.java
--- a/jdk/src/share/classes/sun/dyn/Access.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, 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.
- */
-
-package sun.dyn;
-
-import sun.reflect.Reflection;
-
-/**
- * Access control to this package.
- * Classes in other packages can attempt to acquire the access token,
- * but will fail if they are not recognized as friends.
- * Certain methods in this package, although public, require a non-null
- * access token in order to proceed; they act like package-private methods.
- * @author jrose
- */
-
-public class Access {
-
- private Access() { }
-
- /**
- * The heart of this pattern: The list of classes which are
- * permitted to acquire the access token, and become honorary
- * members of this package.
- */
- private static final String[] FRIENDS = {
- "java.dyn.", "sun.dyn."
- };
-
- /**
- * The following object is NOT public. That's the point of the pattern.
- * It is package-private, so that any member of this package
- * can acquire the access token, and give it away to trusted friends.
- */
- static final Access TOKEN = new Access();
-
- /**
- * @return Access.TOKEN, if the caller is a friend of this package
- */
- public static Access getToken() {
- Class> callc = Reflection.getCallerClass(2);
- if (isFriend(callc))
- return TOKEN;
- else
- throw new IllegalAccessError("bad caller: " + callc);
- }
-
- /** Is the given name the name of a class which could be our friend? */
- public static boolean isFriendName(String name) {
- for (String friend : FRIENDS) {
- if (name.startsWith(friend))
- return true;
- }
- return false;
- }
-
- /** Is the given class a friend? True if {@link #isFriendName},
- * and the given class also shares a class loader with us.
- */
- public static boolean isFriend(Class> c) {
- return isFriendName(c.getName()) && c.getClassLoader() == CLASS_LOADER;
- }
-
- private static final ClassLoader CLASS_LOADER = Access.class.getClassLoader();
-
- /**
- * Throw an IllegalAccessError if the caller does not possess
- * the Access.TOKEN.
- * @param must be Access.TOKEN
- */
- public static void check(Access token) {
- if (token == null)
- fail();
- // else it must be the unique Access.TOKEN
- assert(token == Access.TOKEN);
- }
- private static void fail() {
- final int CALLER_DEPTH = 3;
- // 0: Reflection.getCC, 1: this.fail, 2: Access.*, 3: caller
- Class> callc = Reflection.getCallerClass(CALLER_DEPTH);
- throw new IllegalAccessError("bad caller: " + callc);
- }
-
- static {
- //sun.reflect.Reflection.registerMethodsToFilter(MH.class, "getToken");
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java
--- a/jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,974 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package sun.dyn;
-
-import sun.dyn.util.VerifyType;
-import sun.dyn.util.Wrapper;
-import java.dyn.*;
-import java.util.Arrays;
-import static sun.dyn.MethodHandleNatives.Constants.*;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-
-/**
- * This method handle performs simple conversion or checking of a single argument.
- * @author jrose
- */
-public class AdapterMethodHandle extends BoundMethodHandle {
-
- //MethodHandle vmtarget; // next AMH or BMH in chain or final DMH
- //Object argument; // parameter to the conversion if needed
- //int vmargslot; // which argument slot is affected
- private final int conversion; // the type of conversion: RETYPE_ONLY, etc.
-
- // Constructors in this class *must* be package scoped or private.
- private AdapterMethodHandle(MethodHandle target, MethodType newType,
- long conv, Object convArg) {
- super(newType, convArg, newType.parameterSlotDepth(1+convArgPos(conv)));
- this.conversion = convCode(conv);
- if (MethodHandleNatives.JVM_SUPPORT) {
- // JVM might update VM-specific bits of conversion (ignore)
- MethodHandleNatives.init(this, target, convArgPos(conv));
- }
- }
- private AdapterMethodHandle(MethodHandle target, MethodType newType,
- long conv) {
- this(target, newType, conv, null);
- }
-
- private static final Access IMPL_TOKEN = Access.getToken();
-
- // TO DO: When adapting another MH with a null conversion, clone
- // the target and change its type, instead of adding another layer.
-
- /** Can a JVM-level adapter directly implement the proposed
- * argument conversions, as if by MethodHandles.convertArguments?
- */
- public static boolean canPairwiseConvert(MethodType newType, MethodType oldType) {
- // same number of args, of course
- int len = newType.parameterCount();
- if (len != oldType.parameterCount())
- return false;
-
- // Check return type. (Not much can be done with it.)
- Class> exp = newType.returnType();
- Class> ret = oldType.returnType();
- if (!VerifyType.isNullConversion(ret, exp))
- return false;
-
- // Check args pairwise.
- for (int i = 0; i < len; i++) {
- Class> src = newType.parameterType(i); // source type
- Class> dst = oldType.parameterType(i); // destination type
- if (!canConvertArgument(src, dst))
- return false;
- }
-
- return true;
- }
-
- /** Can a JVM-level adapter directly implement the proposed
- * argument conversion, as if by MethodHandles.convertArguments?
- */
- public static boolean canConvertArgument(Class> src, Class> dst) {
- // ? Retool this logic to use RETYPE_ONLY, CHECK_CAST, etc., as opcodes,
- // so we don't need to repeat so much decision making.
- if (VerifyType.isNullConversion(src, dst)) {
- return true;
- } else if (src.isPrimitive()) {
- if (dst.isPrimitive())
- return canPrimCast(src, dst);
- else
- return canBoxArgument(src, dst);
- } else {
- if (dst.isPrimitive())
- return canUnboxArgument(src, dst);
- else
- return true; // any two refs can be interconverted
- }
- }
-
- /**
- * Create a JVM-level adapter method handle to conform the given method
- * handle to the similar newType, using only pairwise argument conversions.
- * For each argument, convert incoming argument to the exact type needed.
- * Only null conversions are allowed on the return value (until
- * the JVM supports ricochet adapters).
- * The argument conversions allowed are casting, unboxing,
- * integral widening or narrowing, and floating point widening or narrowing.
- * @param token access check
- * @param newType required call type
- * @param target original method handle
- * @return an adapter to the original handle with the desired new type,
- * or the original target if the types are already identical
- * or null if the adaptation cannot be made
- */
- public static MethodHandle makePairwiseConvert(Access token,
- MethodType newType, MethodHandle target) {
- Access.check(token);
- MethodType oldType = target.type();
- if (newType == oldType) return target;
-
- if (!canPairwiseConvert(newType, oldType))
- return null;
- // (after this point, it is an assertion error to fail to convert)
-
- // Find last non-trivial conversion (if any).
- int lastConv = newType.parameterCount()-1;
- while (lastConv >= 0) {
- Class> src = newType.parameterType(lastConv); // source type
- Class> dst = oldType.parameterType(lastConv); // destination type
- if (VerifyType.isNullConversion(src, dst)) {
- --lastConv;
- } else {
- break;
- }
- }
- // Now build a chain of one or more adapters.
- MethodHandle adapter = target;
- MethodType midType = oldType.changeReturnType(newType.returnType());
- for (int i = 0; i <= lastConv; i++) {
- Class> src = newType.parameterType(i); // source type
- Class> dst = midType.parameterType(i); // destination type
- if (VerifyType.isNullConversion(src, dst)) {
- // do nothing: difference is trivial
- continue;
- }
- // Work the current type backward toward the desired caller type:
- if (i != lastConv) {
- midType = midType.changeParameterType(i, src);
- } else {
- // When doing the last (or only) real conversion,
- // force all remaining null conversions to happen also.
- assert(VerifyType.isNullConversion(newType, midType.changeParameterType(i, src)));
- midType = newType;
- }
-
- // Tricky case analysis follows.
- // It parallels canConvertArgument() above.
- if (src.isPrimitive()) {
- if (dst.isPrimitive()) {
- adapter = makePrimCast(token, midType, adapter, i, dst);
- } else {
- adapter = makeBoxArgument(token, midType, adapter, i, dst);
- }
- } else {
- if (dst.isPrimitive()) {
- // Caller has boxed a primitive. Unbox it for the target.
- // The box type must correspond exactly to the primitive type.
- // This is simpler than the powerful set of widening
- // conversions supported by reflect.Method.invoke.
- // Those conversions require a big nest of if/then/else logic,
- // which we prefer to make a user responsibility.
- adapter = makeUnboxArgument(token, midType, adapter, i, dst);
- } else {
- // Simple reference conversion.
- // Note: Do not check for a class hierarchy relation
- // between src and dst. In all cases a 'null' argument
- // will pass the cast conversion.
- adapter = makeCheckCast(token, midType, adapter, i, dst);
- }
- }
- assert(adapter != null);
- assert(adapter.type() == midType);
- }
- if (adapter.type() != newType) {
- // Only trivial conversions remain.
- adapter = makeRetypeOnly(IMPL_TOKEN, newType, adapter);
- assert(adapter != null);
- // Actually, that's because there were no non-trivial ones:
- assert(lastConv == -1);
- }
- assert(adapter.type() == newType);
- return adapter;
- }
-
- /**
- * Create a JVM-level adapter method handle to permute the arguments
- * of the given method.
- * @param token access check
- * @param newType required call type
- * @param target original method handle
- * @param argumentMap for each target argument, position of its source in newType
- * @return an adapter to the original handle with the desired new type,
- * or the original target if the types are already identical
- * and the permutation is null
- * @throws IllegalArgumentException if the adaptation cannot be made
- * directly by a JVM-level adapter, without help from Java code
- */
- public static MethodHandle makePermutation(Access token,
- MethodType newType, MethodHandle target,
- int[] argumentMap) {
- MethodType oldType = target.type();
- boolean nullPermutation = true;
- for (int i = 0; i < argumentMap.length; i++) {
- int pos = argumentMap[i];
- if (pos != i)
- nullPermutation = false;
- if (pos < 0 || pos >= newType.parameterCount()) {
- argumentMap = new int[0]; break;
- }
- }
- if (argumentMap.length != oldType.parameterCount())
- throw newIllegalArgumentException("bad permutation: "+Arrays.toString(argumentMap));
- if (nullPermutation) {
- MethodHandle res = makePairwiseConvert(token, newType, target);
- // well, that was easy
- if (res == null)
- throw newIllegalArgumentException("cannot convert pairwise: "+newType);
- return res;
- }
-
- // Check return type. (Not much can be done with it.)
- Class> exp = newType.returnType();
- Class> ret = oldType.returnType();
- if (!VerifyType.isNullConversion(ret, exp))
- throw newIllegalArgumentException("bad return conversion for "+newType);
-
- // See if the argument types match up.
- for (int i = 0; i < argumentMap.length; i++) {
- int j = argumentMap[i];
- Class> src = newType.parameterType(j);
- Class> dst = oldType.parameterType(i);
- if (!VerifyType.isNullConversion(src, dst))
- throw newIllegalArgumentException("bad argument #"+j+" conversion for "+newType);
- }
-
- // Now figure out a nice mix of SWAP, ROT, DUP, and DROP adapters.
- // A workable greedy algorithm is as follows:
- // Drop unused outgoing arguments (right to left: shallowest first).
- // Duplicate doubly-used outgoing arguments (left to right: deepest first).
- // Then the remaining problem is a true argument permutation.
- // Marshal the outgoing arguments as required from left to right.
- // That is, find the deepest outgoing stack position that does not yet
- // have the correct argument value, and correct at least that position
- // by swapping or rotating in the misplaced value (from a shallower place).
- // If the misplaced value is followed by one or more consecutive values
- // (also misplaced) issue a rotation which brings as many as possible
- // into position. Otherwise make progress with either a swap or a
- // rotation. Prefer the swap as cheaper, but do not use it if it
- // breaks a slot pair. Prefer the rotation over the swap if it would
- // preserve more consecutive values shallower than the target position.
- // When more than one rotation will work (because the required value
- // is already adjacent to the target position), then use a rotation
- // which moves the old value in the target position adjacent to
- // one of its consecutive values. Also, prefer shorter rotation
- // spans, since they use fewer memory cycles for shuffling.
-
- throw new UnsupportedOperationException("NYI");
- }
-
- private static byte basicType(Class> type) {
- if (type == null) return T_VOID;
- switch (Wrapper.forBasicType(type)) {
- case BOOLEAN: return T_BOOLEAN;
- case CHAR: return T_CHAR;
- case FLOAT: return T_FLOAT;
- case DOUBLE: return T_DOUBLE;
- case BYTE: return T_BYTE;
- case SHORT: return T_SHORT;
- case INT: return T_INT;
- case LONG: return T_LONG;
- case OBJECT: return T_OBJECT;
- case VOID: return T_VOID;
- }
- return 99; // T_ILLEGAL or some such
- }
-
- /** Number of stack slots for the given type.
- * Two for T_DOUBLE and T_FLOAT, one for the rest.
- */
- private static int type2size(int type) {
- assert(type >= T_BOOLEAN && type <= T_OBJECT);
- return (type == T_LONG || type == T_DOUBLE) ? 2 : 1;
- }
- private static int type2size(Class> type) {
- return type2size(basicType(type));
- }
-
- /** The given stackMove is the number of slots pushed.
- * It might be negative. Scale it (multiply) by the
- * VM's notion of how an address changes with a push,
- * to get the raw SP change for stackMove.
- * Then shift and mask it into the correct field.
- */
- private static long insertStackMove(int stackMove) {
- // following variable must be long to avoid sign extension after '<<'
- long spChange = stackMove * MethodHandleNatives.JVM_STACK_MOVE_UNIT;
- return (spChange & CONV_STACK_MOVE_MASK) << CONV_STACK_MOVE_SHIFT;
- }
-
- /** Construct an adapter conversion descriptor for a single-argument conversion. */
- private static long makeConv(int convOp, int argnum, int src, int dest) {
- assert(src == (src & 0xF));
- assert(dest == (dest & 0xF));
- assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF);
- int stackMove = type2size(dest) - type2size(src);
- return ((long) argnum << 32 |
- (long) convOp << CONV_OP_SHIFT |
- (int) src << CONV_SRC_TYPE_SHIFT |
- (int) dest << CONV_DEST_TYPE_SHIFT |
- insertStackMove(stackMove)
- );
- }
- private static long makeConv(int convOp, int argnum, int stackMove) {
- assert(convOp >= OP_DUP_ARGS && convOp <= OP_SPREAD_ARGS);
- byte src = 0, dest = 0;
- if (convOp >= OP_COLLECT_ARGS && convOp <= OP_SPREAD_ARGS)
- src = dest = T_OBJECT;
- return ((long) argnum << 32 |
- (long) convOp << CONV_OP_SHIFT |
- (int) src << CONV_SRC_TYPE_SHIFT |
- (int) dest << CONV_DEST_TYPE_SHIFT |
- insertStackMove(stackMove)
- );
- }
- private static long makeSwapConv(int convOp, int srcArg, byte type, int destSlot) {
- assert(convOp >= OP_SWAP_ARGS && convOp <= OP_ROT_ARGS);
- return ((long) srcArg << 32 |
- (long) convOp << CONV_OP_SHIFT |
- (int) type << CONV_SRC_TYPE_SHIFT |
- (int) type << CONV_DEST_TYPE_SHIFT |
- (int) destSlot << CONV_VMINFO_SHIFT
- );
- }
- private static long makeConv(int convOp) {
- assert(convOp == OP_RETYPE_ONLY || convOp == OP_RETYPE_RAW);
- return ((long)-1 << 32) | (convOp << CONV_OP_SHIFT); // stackMove, src, dst all zero
- }
- private static int convCode(long conv) {
- return (int)conv;
- }
- private static int convArgPos(long conv) {
- return (int)(conv >>> 32);
- }
- private static boolean convOpSupported(int convOp) {
- assert(convOp >= 0 && convOp <= CONV_OP_LIMIT);
- return ((1<> CONV_OP_SHIFT; }
-
- /* Return one plus the position of the first non-trivial difference
- * between the given types. This is not a symmetric operation;
- * we are considering adapting the targetType to adapterType.
- * Trivial differences are those which could be ignored by the JVM
- * without subverting the verifier. Otherwise, adaptable differences
- * are ones for which we could create an adapter to make the type change.
- * Return zero if there are no differences (other than trivial ones).
- * Return 1+N if N is the only adaptable argument difference.
- * Return the -2-N where N is the first of several adaptable
- * argument differences.
- * Return -1 if there there are differences which are not adaptable.
- */
- private static int diffTypes(MethodType adapterType,
- MethodType targetType,
- boolean raw) {
- int diff;
- diff = diffReturnTypes(adapterType, targetType, raw);
- if (diff != 0) return diff;
- int nargs = adapterType.parameterCount();
- if (nargs != targetType.parameterCount())
- return -1;
- diff = diffParamTypes(adapterType, 0, targetType, 0, nargs, raw);
- //System.out.println("diff "+adapterType);
- //System.out.println(" "+diff+" "+targetType);
- return diff;
- }
- private static int diffReturnTypes(MethodType adapterType,
- MethodType targetType,
- boolean raw) {
- Class> src = targetType.returnType();
- Class> dst = adapterType.returnType();
- if ((!raw
- ? VerifyType.canPassUnchecked(src, dst)
- : VerifyType.canPassRaw(src, dst)
- ) > 0)
- return 0; // no significant difference
- if (raw && !src.isPrimitive() && !dst.isPrimitive())
- return 0; // can force a reference return (very carefully!)
- //if (false) return 1; // never adaptable!
- return -1; // some significant difference
- }
- private static int diffParamTypes(MethodType adapterType, int astart,
- MethodType targetType, int tstart,
- int nargs, boolean raw) {
- assert(nargs >= 0);
- int res = 0;
- for (int i = 0; i < nargs; i++) {
- Class> src = adapterType.parameterType(astart+i);
- Class> dest = targetType.parameterType(tstart+i);
- if ((!raw
- ? VerifyType.canPassUnchecked(src, dest)
- : VerifyType.canPassRaw(src, dest)
- ) <= 0) {
- // found a difference; is it the only one so far?
- if (res != 0)
- return -1-res; // return -2-i for prev. i
- res = 1+i;
- }
- }
- return res;
- }
-
- /** Can a retyping adapter (alone) validly convert the target to newType? */
- public static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
- return canRetype(newType, targetType, false);
- }
- /** Can a retyping adapter (alone) convert the target to newType?
- * It is allowed to widen subword types and void to int, to make bitwise
- * conversions between float/int and double/long, and to perform unchecked
- * reference conversions on return. This last feature requires that the
- * caller be trusted, and perform explicit cast conversions on return values.
- */
- public static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
- return canRetype(newType, targetType, true);
- }
- static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) {
- if (!convOpSupported(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY)) return false;
- int diff = diffTypes(newType, targetType, raw);
- // %%% This assert is too strong. Factor diff into VerifyType and reconcile.
- assert(raw || (diff == 0) == VerifyType.isNullConversion(newType, targetType));
- return diff == 0;
- }
-
- /** Factory method: Performs no conversions; simply retypes the adapter.
- * Allows unchecked argument conversions pairwise, if they are safe.
- * Returns null if not possible.
- */
- public static MethodHandle makeRetypeOnly(Access token,
- MethodType newType, MethodHandle target) {
- return makeRetype(token, newType, target, false);
- }
- public static MethodHandle makeRetypeRaw(Access token,
- MethodType newType, MethodHandle target) {
- return makeRetype(token, newType, target, true);
- }
- static MethodHandle makeRetype(Access token,
- MethodType newType, MethodHandle target, boolean raw) {
- Access.check(token);
- MethodType oldType = target.type();
- if (oldType == newType) return target;
- if (!canRetype(newType, oldType, raw))
- return null;
- // TO DO: clone the target guy, whatever he is, with new type.
- return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
- }
-
- static MethodHandle makeVarargsCollector(Access token,
- MethodHandle target, Class> arrayType) {
- Access.check(token);
- return new AsVarargsCollector(target, arrayType);
- }
-
- static class AsVarargsCollector extends AdapterMethodHandle {
- final MethodHandle target;
- final Class> arrayType;
- MethodHandle cache;
-
- AsVarargsCollector(MethodHandle target, Class> arrayType) {
- super(target, target.type(), makeConv(OP_RETYPE_ONLY));
- this.target = target;
- this.arrayType = arrayType;
- this.cache = target.asCollector(arrayType, 0);
- }
-
- @Override
- public boolean isVarargsCollector() {
- return true;
- }
-
- @Override
- public MethodHandle asType(MethodType newType) {
- MethodType type = this.type();
- int collectArg = type.parameterCount() - 1;
- int newArity = newType.parameterCount();
- if (newArity == collectArg+1 &&
- type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
- // if arity and trailing parameter are compatible, do normal thing
- return super.asType(newType);
- }
- // check cache
- if (cache.type().parameterCount() == newArity)
- return cache.asType(newType);
- // build and cache a collector
- int arrayLength = newArity - collectArg;
- MethodHandle collector;
- try {
- collector = target.asCollector(arrayType, arrayLength);
- } catch (IllegalArgumentException ex) {
- throw new WrongMethodTypeException("cannot build collector");
- }
- cache = collector;
- return collector.asType(newType);
- }
-
- public MethodHandle asVarargsCollector(Class> arrayType) {
- MethodType type = this.type();
- if (type.parameterType(type.parameterCount()-1) == arrayType)
- return this;
- return super.asVarargsCollector(arrayType);
- }
- }
-
- /** Can a checkcast adapter validly convert the target to newType?
- * The JVM supports all kind of reference casts, even silly ones.
- */
- public static boolean canCheckCast(MethodType newType, MethodType targetType,
- int arg, Class> castType) {
- if (!convOpSupported(OP_CHECK_CAST)) return false;
- Class> src = newType.parameterType(arg);
- Class> dst = targetType.parameterType(arg);
- if (!canCheckCast(src, castType)
- || !VerifyType.isNullConversion(castType, dst))
- return false;
- int diff = diffTypes(newType, targetType, false);
- return (diff == arg+1); // arg is sole non-trivial diff
- }
- /** Can an primitive conversion adapter validly convert src to dst? */
- public static boolean canCheckCast(Class> src, Class> dst) {
- return (!src.isPrimitive() && !dst.isPrimitive());
- }
-
- /** Factory method: Forces a cast at the given argument.
- * The castType is the target of the cast, and can be any type
- * with a null conversion to the corresponding target parameter.
- * Return null if this cannot be done.
- */
- public static MethodHandle makeCheckCast(Access token,
- MethodType newType, MethodHandle target,
- int arg, Class> castType) {
- Access.check(token);
- if (!canCheckCast(newType, target.type(), arg, castType))
- return null;
- long conv = makeConv(OP_CHECK_CAST, arg, T_OBJECT, T_OBJECT);
- return new AdapterMethodHandle(target, newType, conv, castType);
- }
-
- /** Can an primitive conversion adapter validly convert the target to newType?
- * The JVM currently supports all conversions except those between
- * floating and integral types.
- */
- public static boolean canPrimCast(MethodType newType, MethodType targetType,
- int arg, Class> convType) {
- if (!convOpSupported(OP_PRIM_TO_PRIM)) return false;
- Class> src = newType.parameterType(arg);
- Class> dst = targetType.parameterType(arg);
- if (!canPrimCast(src, convType)
- || !VerifyType.isNullConversion(convType, dst))
- return false;
- int diff = diffTypes(newType, targetType, false);
- return (diff == arg+1); // arg is sole non-trivial diff
- }
- /** Can an primitive conversion adapter validly convert src to dst? */
- public static boolean canPrimCast(Class> src, Class> dst) {
- if (src == dst || !src.isPrimitive() || !dst.isPrimitive()) {
- return false;
- } else if (Wrapper.forPrimitiveType(dst).isFloating()) {
- // both must be floating types
- return Wrapper.forPrimitiveType(src).isFloating();
- } else {
- // both are integral, and all combinations work fine
- assert(Wrapper.forPrimitiveType(src).isIntegral() &&
- Wrapper.forPrimitiveType(dst).isIntegral());
- return true;
- }
- }
-
- /** Factory method: Truncate the given argument with zero or sign extension,
- * and/or convert between single and doubleword versions of integer or float.
- * The convType is the target of the conversion, and can be any type
- * with a null conversion to the corresponding target parameter.
- * Return null if this cannot be done.
- */
- public static MethodHandle makePrimCast(Access token,
- MethodType newType, MethodHandle target,
- int arg, Class> convType) {
- Access.check(token);
- MethodType oldType = target.type();
- if (!canPrimCast(newType, oldType, arg, convType))
- return null;
- Class> src = newType.parameterType(arg);
- long conv = makeConv(OP_PRIM_TO_PRIM, arg, basicType(src), basicType(convType));
- return new AdapterMethodHandle(target, newType, conv);
- }
-
- /** Can an unboxing conversion validly convert src to dst?
- * The JVM currently supports all kinds of casting and unboxing.
- * The convType is the unboxed type; it can be either a primitive or wrapper.
- */
- public static boolean canUnboxArgument(MethodType newType, MethodType targetType,
- int arg, Class> convType) {
- if (!convOpSupported(OP_REF_TO_PRIM)) return false;
- Class> src = newType.parameterType(arg);
- Class> dst = targetType.parameterType(arg);
- Class> boxType = Wrapper.asWrapperType(convType);
- convType = Wrapper.asPrimitiveType(convType);
- if (!canCheckCast(src, boxType)
- || boxType == convType
- || !VerifyType.isNullConversion(convType, dst))
- return false;
- int diff = diffTypes(newType, targetType, false);
- return (diff == arg+1); // arg is sole non-trivial diff
- }
- /** Can an primitive unboxing adapter validly convert src to dst? */
- public static boolean canUnboxArgument(Class> src, Class> dst) {
- return (!src.isPrimitive() && Wrapper.asPrimitiveType(dst).isPrimitive());
- }
-
- /** Factory method: Unbox the given argument.
- * Return null if this cannot be done.
- */
- public static MethodHandle makeUnboxArgument(Access token,
- MethodType newType, MethodHandle target,
- int arg, Class> convType) {
- MethodType oldType = target.type();
- Class> src = newType.parameterType(arg);
- Class> dst = oldType.parameterType(arg);
- Class> boxType = Wrapper.asWrapperType(convType);
- Class> primType = Wrapper.asPrimitiveType(convType);
- if (!canUnboxArgument(newType, oldType, arg, convType))
- return null;
- MethodType castDone = newType;
- if (!VerifyType.isNullConversion(src, boxType))
- castDone = newType.changeParameterType(arg, boxType);
- long conv = makeConv(OP_REF_TO_PRIM, arg, T_OBJECT, basicType(primType));
- MethodHandle adapter = new AdapterMethodHandle(target, castDone, conv, boxType);
- if (castDone == newType)
- return adapter;
- return makeCheckCast(token, newType, adapter, arg, boxType);
- }
-
- /** Can an primitive boxing adapter validly convert src to dst? */
- public static boolean canBoxArgument(Class> src, Class> dst) {
- if (!convOpSupported(OP_PRIM_TO_REF)) return false;
- throw new UnsupportedOperationException("NYI");
- }
-
- /** Factory method: Unbox the given argument.
- * Return null if this cannot be done.
- */
- public static MethodHandle makeBoxArgument(Access token,
- MethodType newType, MethodHandle target,
- int arg, Class> convType) {
- // this is difficult to do in the JVM because it must GC
- return null;
- }
-
- /** Can an adapter simply drop arguments to convert the target to newType? */
- public static boolean canDropArguments(MethodType newType, MethodType targetType,
- int dropArgPos, int dropArgCount) {
- if (dropArgCount == 0)
- return canRetypeOnly(newType, targetType);
- if (!convOpSupported(OP_DROP_ARGS)) return false;
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- int nptypes = newType.parameterCount();
- // parameter types must be the same up to the drop point
- if (dropArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, dropArgPos, false) != 0)
- return false;
- int afterPos = dropArgPos + dropArgCount;
- int afterCount = nptypes - afterPos;
- if (dropArgPos < 0 || dropArgPos >= nptypes ||
- dropArgCount < 1 || afterPos > nptypes ||
- targetType.parameterCount() != nptypes - dropArgCount)
- return false;
- // parameter types after the drop point must also be the same
- if (afterCount != 0 && diffParamTypes(newType, afterPos, targetType, dropArgPos, afterCount, false) != 0)
- return false;
- return true;
- }
-
- /** Factory method: Drop selected arguments.
- * Allow unchecked retyping of remaining arguments, pairwise.
- * Return null if this is not possible.
- */
- public static MethodHandle makeDropArguments(Access token,
- MethodType newType, MethodHandle target,
- int dropArgPos, int dropArgCount) {
- Access.check(token);
- if (dropArgCount == 0)
- return makeRetypeOnly(IMPL_TOKEN, newType, target);
- if (!canDropArguments(newType, target.type(), dropArgPos, dropArgCount))
- return null;
- // in arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ]
- // out arglist: [0: ...keep1 | dpos: keep2... ]
- int keep2InPos = dropArgPos + dropArgCount;
- int dropSlot = newType.parameterSlotDepth(keep2InPos);
- int keep1InSlot = newType.parameterSlotDepth(dropArgPos);
- int slotCount = keep1InSlot - dropSlot;
- assert(slotCount >= dropArgCount);
- assert(target.type().parameterSlotCount() + slotCount == newType.parameterSlotCount());
- long conv = makeConv(OP_DROP_ARGS, dropArgPos + dropArgCount - 1, -slotCount);
- return new AdapterMethodHandle(target, newType, conv);
- }
-
- /** Can an adapter duplicate an argument to convert the target to newType? */
- public static boolean canDupArguments(MethodType newType, MethodType targetType,
- int dupArgPos, int dupArgCount) {
- if (!convOpSupported(OP_DUP_ARGS)) return false;
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- int nptypes = newType.parameterCount();
- if (dupArgCount < 0 || dupArgPos + dupArgCount > nptypes)
- return false;
- if (targetType.parameterCount() != nptypes + dupArgCount)
- return false;
- // parameter types must be the same up to the duplicated arguments
- if (diffParamTypes(newType, 0, targetType, 0, nptypes, false) != 0)
- return false;
- // duplicated types must be, well, duplicates
- if (diffParamTypes(newType, dupArgPos, targetType, nptypes, dupArgCount, false) != 0)
- return false;
- return true;
- }
-
- /** Factory method: Duplicate the selected argument.
- * Return null if this is not possible.
- */
- public static MethodHandle makeDupArguments(Access token,
- MethodType newType, MethodHandle target,
- int dupArgPos, int dupArgCount) {
- Access.check(token);
- if (!canDupArguments(newType, target.type(), dupArgPos, dupArgCount))
- return null;
- if (dupArgCount == 0)
- return target;
- // in arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... ]
- // out arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... | dup... ]
- int keep2InPos = dupArgPos + dupArgCount;
- int dupSlot = newType.parameterSlotDepth(keep2InPos);
- int keep1InSlot = newType.parameterSlotDepth(dupArgPos);
- int slotCount = keep1InSlot - dupSlot;
- assert(target.type().parameterSlotCount() - slotCount == newType.parameterSlotCount());
- long conv = makeConv(OP_DUP_ARGS, dupArgPos + dupArgCount - 1, slotCount);
- return new AdapterMethodHandle(target, newType, conv);
- }
-
- /** Can an adapter swap two arguments to convert the target to newType? */
- public static boolean canSwapArguments(MethodType newType, MethodType targetType,
- int swapArg1, int swapArg2) {
- if (!convOpSupported(OP_SWAP_ARGS)) return false;
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- if (swapArg1 >= swapArg2) return false; // caller resp
- int nptypes = newType.parameterCount();
- if (targetType.parameterCount() != nptypes)
- return false;
- if (swapArg1 < 0 || swapArg2 >= nptypes)
- return false;
- if (diffParamTypes(newType, 0, targetType, 0, swapArg1, false) != 0)
- return false;
- if (diffParamTypes(newType, swapArg1, targetType, swapArg2, 1, false) != 0)
- return false;
- if (diffParamTypes(newType, swapArg1+1, targetType, swapArg1+1, swapArg2-swapArg1-1, false) != 0)
- return false;
- if (diffParamTypes(newType, swapArg2, targetType, swapArg1, 1, false) != 0)
- return false;
- if (diffParamTypes(newType, swapArg2+1, targetType, swapArg2+1, nptypes-swapArg2-1, false) != 0)
- return false;
- return true;
- }
-
- /** Factory method: Swap the selected arguments.
- * Return null if this is not possible.
- */
- public static MethodHandle makeSwapArguments(Access token,
- MethodType newType, MethodHandle target,
- int swapArg1, int swapArg2) {
- Access.check(token);
- if (swapArg1 == swapArg2)
- return target;
- if (swapArg1 > swapArg2) { int t = swapArg1; swapArg1 = swapArg2; swapArg2 = t; }
- if (!canSwapArguments(newType, target.type(), swapArg1, swapArg2))
- return null;
- Class> swapType = newType.parameterType(swapArg1);
- // in arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
- // out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
- int swapSlot2 = newType.parameterSlotDepth(swapArg2 + 1);
- long conv = makeSwapConv(OP_SWAP_ARGS, swapArg1, basicType(swapType), swapSlot2);
- return new AdapterMethodHandle(target, newType, conv);
- }
-
- static int positiveRotation(int argCount, int rotateBy) {
- assert(argCount > 0);
- if (rotateBy >= 0) {
- if (rotateBy < argCount)
- return rotateBy;
- return rotateBy % argCount;
- } else if (rotateBy >= -argCount) {
- return rotateBy + argCount;
- } else {
- return (-1-((-1-rotateBy) % argCount)) + argCount;
- }
- }
-
- final static int MAX_ARG_ROTATION = 1;
-
- /** Can an adapter rotate arguments to convert the target to newType? */
- public static boolean canRotateArguments(MethodType newType, MethodType targetType,
- int firstArg, int argCount, int rotateBy) {
- if (!convOpSupported(OP_ROT_ARGS)) return false;
- if (argCount <= 2) return false; // must be a swap, not a rotate
- rotateBy = positiveRotation(argCount, rotateBy);
- if (rotateBy == 0) return false; // no rotation
- if (rotateBy > MAX_ARG_ROTATION && rotateBy < argCount - MAX_ARG_ROTATION)
- return false; // too many argument positions
- // Rotate incoming args right N to the out args, N in 1..(argCouunt-1).
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- int nptypes = newType.parameterCount();
- if (targetType.parameterCount() != nptypes)
- return false;
- if (firstArg < 0 || firstArg >= nptypes) return false;
- int argLimit = firstArg + argCount;
- if (argLimit > nptypes) return false;
- if (diffParamTypes(newType, 0, targetType, 0, firstArg, false) != 0)
- return false;
- int newChunk1 = argCount - rotateBy, newChunk2 = rotateBy;
- // swap new chunk1 with target chunk2
- if (diffParamTypes(newType, firstArg, targetType, argLimit-newChunk1, newChunk1, false) != 0)
- return false;
- // swap new chunk2 with target chunk1
- if (diffParamTypes(newType, firstArg+newChunk1, targetType, firstArg, newChunk2, false) != 0)
- return false;
- return true;
- }
-
- /** Factory method: Rotate the selected argument range.
- * Return null if this is not possible.
- */
- public static MethodHandle makeRotateArguments(Access token,
- MethodType newType, MethodHandle target,
- int firstArg, int argCount, int rotateBy) {
- Access.check(token);
- rotateBy = positiveRotation(argCount, rotateBy);
- if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy))
- return null;
- // Decide whether it should be done as a right or left rotation,
- // on the JVM stack. Return the number of stack slots to rotate by,
- // positive if right, negative if left.
- int limit = firstArg + argCount;
- int depth0 = newType.parameterSlotDepth(firstArg);
- int depth1 = newType.parameterSlotDepth(limit-rotateBy);
- int depth2 = newType.parameterSlotDepth(limit);
- int chunk1Slots = depth0 - depth1; assert(chunk1Slots > 0);
- int chunk2Slots = depth1 - depth2; assert(chunk2Slots > 0);
- // From here on out, it assumes a single-argument shift.
- assert(MAX_ARG_ROTATION == 1);
- int srcArg, dstArg;
- byte basicType;
- if (chunk2Slots <= chunk1Slots) {
- // Rotate right/down N (rotateBy = +N, N small, c2 small):
- // in arglist: [0: ...keep1 | arg1: c1... | limit-N: c2 | limit: keep2... ]
- // out arglist: [0: ...keep1 | arg1: c2 | arg1+N: c1... | limit: keep2... ]
- srcArg = limit-1;
- dstArg = firstArg;
- basicType = basicType(newType.parameterType(srcArg));
- assert(chunk2Slots == type2size(basicType));
- } else {
- // Rotate left/up N (rotateBy = -N, N small, c1 small):
- // in arglist: [0: ...keep1 | arg1: c1 | arg1+N: c2... | limit: keep2... ]
- // out arglist: [0: ...keep1 | arg1: c2 ... | limit-N: c1 | limit: keep2... ]
- srcArg = firstArg;
- dstArg = limit-1;
- basicType = basicType(newType.parameterType(srcArg));
- assert(chunk1Slots == type2size(basicType));
- }
- int dstSlot = newType.parameterSlotDepth(dstArg + 1);
- long conv = makeSwapConv(OP_ROT_ARGS, srcArg, basicType, dstSlot);
- return new AdapterMethodHandle(target, newType, conv);
- }
-
- /** Can an adapter spread an argument to convert the target to newType? */
- public static boolean canSpreadArguments(MethodType newType, MethodType targetType,
- Class> spreadArgType, int spreadArgPos, int spreadArgCount) {
- if (!convOpSupported(OP_SPREAD_ARGS)) return false;
- if (diffReturnTypes(newType, targetType, false) != 0)
- return false;
- int nptypes = newType.parameterCount();
- // parameter types must be the same up to the spread point
- if (spreadArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, spreadArgPos, false) != 0)
- return false;
- int afterPos = spreadArgPos + spreadArgCount;
- int afterCount = nptypes - (spreadArgPos + 1);
- if (spreadArgPos < 0 || spreadArgPos >= nptypes ||
- spreadArgCount < 0 ||
- targetType.parameterCount() != afterPos + afterCount)
- return false;
- // parameter types after the spread point must also be the same
- if (afterCount != 0 && diffParamTypes(newType, spreadArgPos+1, targetType, afterPos, afterCount, false) != 0)
- return false;
- // match the array element type to the spread arg types
- Class> rawSpreadArgType = newType.parameterType(spreadArgPos);
- if (rawSpreadArgType != spreadArgType && !canCheckCast(rawSpreadArgType, spreadArgType))
- return false;
- for (int i = 0; i < spreadArgCount; i++) {
- Class> src = VerifyType.spreadArgElementType(spreadArgType, i);
- Class> dst = targetType.parameterType(spreadArgPos + i);
- if (src == null || !VerifyType.isNullConversion(src, dst))
- return false;
- }
- return true;
- }
-
-
- /** Factory method: Spread selected argument. */
- public static MethodHandle makeSpreadArguments(Access token,
- MethodType newType, MethodHandle target,
- Class> spreadArgType, int spreadArgPos, int spreadArgCount) {
- Access.check(token);
- MethodType targetType = target.type();
- if (!canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount))
- return null;
- // in arglist: [0: ...keep1 | spos: spreadArg | spos+1: keep2... ]
- // out arglist: [0: ...keep1 | spos: spread... | spos+scount: keep2... ]
- int keep2OutPos = spreadArgPos + spreadArgCount;
- int spreadSlot = targetType.parameterSlotDepth(keep2OutPos);
- int keep1OutSlot = targetType.parameterSlotDepth(spreadArgPos);
- int slotCount = keep1OutSlot - spreadSlot;
- assert(spreadSlot == newType.parameterSlotDepth(spreadArgPos+1));
- assert(slotCount >= spreadArgCount);
- long conv = makeConv(OP_SPREAD_ARGS, spreadArgPos, slotCount-1);
- MethodHandle res = new AdapterMethodHandle(target, newType, conv, spreadArgType);
- assert(res.type().parameterType(spreadArgPos) == spreadArgType);
- return res;
- }
-
- // TO DO: makeCollectArguments, makeFlyby, makeRicochet
-
- @Override
- public String toString() {
- return MethodHandleImpl.getNameString(IMPL_TOKEN, nonAdapter((MethodHandle)vmtarget), this);
- }
-
- private static MethodHandle nonAdapter(MethodHandle mh) {
- while (mh instanceof AdapterMethodHandle) {
- mh = (MethodHandle) mh.vmtarget;
- }
- return mh;
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/BoundMethodHandle.java
--- a/jdk/src/share/classes/sun/dyn/BoundMethodHandle.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.
- */
-
-package sun.dyn;
-
-import sun.dyn.util.VerifyType;
-import sun.dyn.util.Wrapper;
-import java.dyn.*;
-import java.util.List;
-import sun.dyn.MethodHandleNatives.Constants;
-import static sun.dyn.MethodHandleImpl.IMPL_LOOKUP;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-
-/**
- * The flavor of method handle which emulates an invoke instruction
- * on a predetermined argument. The JVM dispatches to the correct method
- * when the handle is created, not when it is invoked.
- * @author jrose
- */
-public class BoundMethodHandle extends MethodHandle {
- //MethodHandle vmtarget; // next BMH or final DMH or methodOop
- private final Object argument; // argument to insert
- private final int vmargslot; // position at which it is inserted
-
- private static final Access IMPL_TOKEN = Access.getToken();
- private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(IMPL_TOKEN);
-
- // Constructors in this class *must* be package scoped or private.
-
- /** Bind a direct MH to its receiver (or first ref. argument).
- * The JVM will pre-dispatch the MH if it is not already static.
- */
- BoundMethodHandle(DirectMethodHandle mh, Object argument) {
- super(Access.TOKEN, mh.type().dropParameterTypes(0, 1));
- // check the type now, once for all:
- this.argument = checkReferenceArgument(argument, mh, 0);
- this.vmargslot = this.type().parameterSlotCount();
- if (MethodHandleNatives.JVM_SUPPORT) {
- this.vmtarget = null; // maybe updated by JVM
- MethodHandleNatives.init(this, mh, 0);
- } else {
- this.vmtarget = mh;
- }
- }
-
- /** Insert an argument into an arbitrary method handle.
- * If argnum is zero, inserts the first argument, etc.
- * The argument type must be a reference.
- */
- BoundMethodHandle(MethodHandle mh, Object argument, int argnum) {
- this(mh.type().dropParameterTypes(argnum, argnum+1),
- mh, argument, argnum);
- }
-
- /** Insert an argument into an arbitrary method handle.
- * If argnum is zero, inserts the first argument, etc.
- */
- BoundMethodHandle(MethodType type, MethodHandle mh, Object argument, int argnum) {
- super(Access.TOKEN, type);
- if (mh.type().parameterType(argnum).isPrimitive())
- this.argument = bindPrimitiveArgument(argument, mh, argnum);
- else {
- this.argument = checkReferenceArgument(argument, mh, argnum);
- }
- this.vmargslot = type.parameterSlotDepth(argnum);
- initTarget(mh, argnum);
- }
-
- private void initTarget(MethodHandle mh, int argnum) {
- if (MethodHandleNatives.JVM_SUPPORT) {
- this.vmtarget = null; // maybe updated by JVM
- MethodHandleNatives.init(this, mh, argnum);
- } else {
- this.vmtarget = mh;
- }
- }
-
- /** For the AdapterMethodHandle subclass.
- */
- BoundMethodHandle(MethodType type, Object argument, int vmargslot) {
- super(Access.TOKEN, type);
- this.argument = argument;
- this.vmargslot = vmargslot;
- assert(this instanceof AdapterMethodHandle);
- }
-
- /** Initialize the current object as a self-bound method handle, binding it
- * as the first argument of the method handle {@code entryPoint}.
- * The invocation type of the resulting method handle will be the
- * same as {@code entryPoint}, except that the first argument
- * type will be dropped.
- */
- protected BoundMethodHandle(Access token, MethodHandle entryPoint) {
- super(token, entryPoint.type().dropParameterTypes(0, 1));
- this.argument = this; // kludge; get rid of
- this.vmargslot = this.type().parameterSlotDepth(0);
- initTarget(entryPoint, 0);
- }
-
- /** Make sure the given {@code argument} can be used as {@code argnum}-th
- * parameter of the given method handle {@code mh}, which must be a reference.
- *
- * If this fails, throw a suitable {@code WrongMethodTypeException},
- * which will prevent the creation of an illegally typed bound
- * method handle.
- */
- final static Object checkReferenceArgument(Object argument, MethodHandle mh, int argnum) {
- Class> ptype = mh.type().parameterType(argnum);
- if (ptype.isPrimitive()) {
- // fail
- } else if (argument == null) {
- return null;
- } else if (VerifyType.isNullReferenceConversion(argument.getClass(), ptype)) {
- return argument;
- }
- throw badBoundArgumentException(argument, mh, argnum);
- }
-
- /** Make sure the given {@code argument} can be used as {@code argnum}-th
- * parameter of the given method handle {@code mh}, which must be a primitive.
- *
- * If this fails, throw a suitable {@code WrongMethodTypeException},
- * which will prevent the creation of an illegally typed bound
- * method handle.
- */
- final static Object bindPrimitiveArgument(Object argument, MethodHandle mh, int argnum) {
- Class> ptype = mh.type().parameterType(argnum);
- Wrapper wrap = Wrapper.forPrimitiveType(ptype);
- Object zero = wrap.zero();
- if (zero == null) {
- // fail
- } else if (argument == null) {
- if (ptype != int.class && wrap.isSubwordOrInt())
- return Integer.valueOf(0);
- else
- return zero;
- } else if (VerifyType.isNullReferenceConversion(argument.getClass(), zero.getClass())) {
- if (ptype != int.class && wrap.isSubwordOrInt())
- return Wrapper.INT.wrap(argument);
- else
- return argument;
- }
- throw badBoundArgumentException(argument, mh, argnum);
- }
-
- final static RuntimeException badBoundArgumentException(Object argument, MethodHandle mh, int argnum) {
- String atype = (argument == null) ? "null" : argument.getClass().toString();
- return new WrongMethodTypeException("cannot bind "+atype+" argument to parameter #"+argnum+" of "+mh.type());
- }
-
- @Override
- public String toString() {
- return MethodHandleImpl.addTypeString(baseName(), this);
- }
-
- /** Component of toString() before the type string. */
- protected String baseName() {
- MethodHandle mh = this;
- while (mh instanceof BoundMethodHandle) {
- Object info = MethodHandleNatives.getTargetInfo(mh);
- if (info instanceof MethodHandle) {
- mh = (MethodHandle) info;
- } else {
- String name = null;
- if (info instanceof MemberName)
- name = ((MemberName)info).getName();
- if (name != null)
- return name;
- else
- return noParens(super.toString()); // "invoke", probably
- }
- assert(mh != this);
- }
- return noParens(mh.toString());
- }
-
- private static String noParens(String str) {
- int paren = str.indexOf('(');
- if (paren >= 0) str = str.substring(0, paren);
- return str;
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/CallSiteImpl.java
--- a/jdk/src/share/classes/sun/dyn/CallSiteImpl.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.
- */
-
-package sun.dyn;
-
-import java.dyn.*;
-import static sun.dyn.MemberName.uncaughtException;
-
-/**
- * Parts of CallSite known to the JVM.
- * @author jrose
- */
-public class CallSiteImpl {
- // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
- static CallSite makeSite(MethodHandle bootstrapMethod,
- // Callee information:
- String name, MethodType type,
- // Extra arguments for BSM, if any:
- Object info,
- // Caller information:
- MemberName callerMethod, int callerBCI) {
- Class> callerClass = callerMethod.getDeclaringClass();
- Object caller;
- if (bootstrapMethod.type().parameterType(0) == Class.class && TRANSITIONAL_BEFORE_PFD)
- caller = callerClass; // remove for PFD
- else
- caller = MethodHandleImpl.IMPL_LOOKUP.in(callerClass);
- if (bootstrapMethod == null && TRANSITIONAL_BEFORE_PFD) {
- // If there is no bootstrap method, throw IncompatibleClassChangeError.
- // This is a valid generic error type for resolution (JLS 12.3.3).
- throw new IncompatibleClassChangeError
- ("Class "+callerClass.getName()+" has not declared a bootstrap method for invokedynamic");
- }
- CallSite site;
- try {
- Object binding;
- info = maybeReBox(info);
- if (info == null) {
- binding = bootstrapMethod.invokeGeneric(caller, name, type);
- } else if (!info.getClass().isArray()) {
- binding = bootstrapMethod.invokeGeneric(caller, name, type, info);
- } else {
- Object[] argv = (Object[]) info;
- if (3 + argv.length > 255)
- new InvokeDynamicBootstrapError("too many bootstrap method arguments");
- MethodType bsmType = bootstrapMethod.type();
- if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
- binding = bootstrapMethod.invokeGeneric(caller, name, type, argv);
- else
- binding = MethodHandles.spreadInvoker(bsmType, 3)
- .invokeGeneric(bootstrapMethod, caller, name, type, argv);
- }
- //System.out.println("BSM for "+name+type+" => "+binding);
- if (binding instanceof CallSite) {
- site = (CallSite) binding;
- } else if (binding instanceof MethodHandle && TRANSITIONAL_BEFORE_PFD) {
- // Transitional!
- MethodHandle target = (MethodHandle) binding;
- site = new ConstantCallSite(target);
- } else {
- throw new ClassCastException("bootstrap method failed to produce a CallSite");
- }
- if (TRANSITIONAL_BEFORE_PFD)
- PRIVATE_INITIALIZE_CALL_SITE.invokeExact(site, name, type,
- callerMethod, callerBCI);
- assert(site.getTarget() != null);
- assert(site.getTarget().type().equals(type));
- } catch (Throwable ex) {
- InvokeDynamicBootstrapError bex;
- if (ex instanceof InvokeDynamicBootstrapError)
- bex = (InvokeDynamicBootstrapError) ex;
- else
- bex = new InvokeDynamicBootstrapError("call site initialization exception", ex);
- throw bex;
- }
- return site;
- }
-
- private static boolean TRANSITIONAL_BEFORE_PFD = true; // FIXME: remove for PFD
-
- private static Object maybeReBox(Object x) {
- if (x instanceof Integer) {
- int xi = (int) x;
- if (xi == (byte) xi)
- x = xi; // must rebox; see JLS 5.1.7
- return x;
- } else if (x instanceof Object[]) {
- Object[] xa = (Object[]) x;
- for (int i = 0; i < xa.length; i++) {
- if (xa[i] instanceof Integer)
- xa[i] = maybeReBox(xa[i]);
- }
- return xa;
- } else {
- return x;
- }
- }
-
- // This method is private in CallSite because it touches private fields in CallSite.
- // These private fields (vmmethod, vmindex) are specific to the JVM.
- private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE;
- static {
- try {
- PRIVATE_INITIALIZE_CALL_SITE =
- !TRANSITIONAL_BEFORE_PFD ? null :
- MethodHandleImpl.IMPL_LOOKUP.findVirtual(CallSite.class, "initializeFromJVM",
- MethodType.methodType(void.class,
- String.class, MethodType.class,
- MemberName.class, int.class));
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- }
-
- public static void setCallSiteTarget(Access token, CallSite site, MethodHandle target) {
- Access.check(token);
- MethodHandleNatives.setCallSiteTarget(site, target);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/DirectMethodHandle.java
--- a/jdk/src/share/classes/sun/dyn/DirectMethodHandle.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, 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.
- */
-
-package sun.dyn;
-
-import java.dyn.*;
-import static sun.dyn.MethodHandleNatives.Constants.*;
-
-/**
- * The flavor of method handle which emulates invokespecial or invokestatic.
- * @author jrose
- */
-class DirectMethodHandle extends MethodHandle {
- //inherited oop vmtarget; // methodOop or virtual class/interface oop
- private final int vmindex; // method index within class or interface
- { vmindex = VM_INDEX_UNINITIALIZED; } // JVM may change this
-
- // Constructors in this class *must* be package scoped or private.
- DirectMethodHandle(MethodType mtype, MemberName m, boolean doDispatch, Class> lookupClass) {
- super(Access.TOKEN, mtype);
-
- assert(m.isMethod() || !doDispatch && m.isConstructor());
- if (!m.isResolved())
- throw new InternalError();
-
- MethodHandleNatives.init(this, (Object) m, doDispatch, lookupClass);
- }
-
- boolean isValid() {
- return (vmindex != VM_INDEX_UNINITIALIZED);
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/FilterGeneric.java
--- a/jdk/src/share/classes/sun/dyn/FilterGeneric.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4496 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.
- */
-
-package sun.dyn;
-
-import java.dyn.*;
-import java.lang.reflect.*;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-
-/**
- * These adapters apply arbitrary conversions to arguments
- * on the way to a ultimate target.
- * For simplicity, these are all generically typed.
- * @author jrose
- */
-class FilterGeneric {
- // type for the incoming call (will be generic)
- private final MethodType entryType;
- // prototype adapters (clone and customize for each new target & conversion!)
- private final Adapter[] adapters;
-
- /** Compute and cache information common to all filtering adapters
- * with the given generic type
- */
- FilterGeneric(MethodType entryType) {
- this.entryType = entryType;
- int tableSize = Kind.LIMIT.invokerIndex(1 + entryType.parameterCount());
- this.adapters = new Adapter[tableSize];
- }
-
- Adapter getAdapter(Kind kind, int pos) {
- int index = kind.invokerIndex(pos);
- Adapter ad = adapters[index];
- if (ad != null) return ad;
- ad = findAdapter(entryType, kind, pos);
- if (ad == null)
- ad = buildAdapterFromBytecodes(entryType, kind, pos);
- adapters[index] = ad;
- return ad;
- }
-
- Adapter makeInstance(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
- Adapter ad = getAdapter(kind, pos);
- return ad.makeInstance(ad.prototypeEntryPoint(), filter, target);
- }
-
- /** Build an adapter of the given generic type, which invokes filter
- * on the selected incoming argument before passing it to the target.
- * @param pos the argument to filter
- * @param filter the function to call on the argument
- * @param target the target to call with the modified argument list
- * @return an adapter method handle
- */
- public static MethodHandle makeArgumentFilter(int pos, MethodHandle filter, MethodHandle target) {
- return make(Kind.value, pos, filter, target);
- }
-
- /** Build an adapter of the given generic type, which invokes a combiner
- * on a selected group of leading arguments.
- * The result of the combiner is prepended before all those arguments.
- * @param combiner the function to call on the selected leading arguments
- * @param target the target to call with the modified argument list
- * @return an adapter method handle
- */
- public static MethodHandle makeArgumentFolder(MethodHandle combiner, MethodHandle target) {
- int num = combiner.type().parameterCount();
- return make(Kind.fold, num, combiner, target);
- }
-
- /** Build an adapter of the given generic type, which invokes a filter
- * on the incoming arguments, reified as a group.
- * The argument may be modified (by side effects in the filter).
- * The arguments, possibly modified, are passed on to the target.
- * @param filter the function to call on the arguments
- * @param target the target to call with the possibly-modified argument list
- * @return an adapter method handle
- */
- public static MethodHandle makeFlyby(MethodHandle filter, MethodHandle target) {
- return make(Kind.flyby, 0, filter, target);
- }
-
- /** Build an adapter of the given generic type, which invokes a collector
- * on the selected incoming argument and all following arguments.
- * The result of the collector replaces all those arguments.
- * @param collector the function to call on the selected trailing arguments
- * @param target the target to call with the modified argument list
- * @return an adapter method handle
- */
- public static MethodHandle makeArgumentCollector(MethodHandle collector, MethodHandle target) {
- int pos = target.type().parameterCount() - 1;
- return make(Kind.collect, pos, collector, target);
- }
-
- static MethodHandle make(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
- FilterGeneric fgen = of(kind, pos, filter.type(), target.type());
- return fgen.makeInstance(kind, pos, filter, target);
- }
-
- /** Return the adapter information for this target and filter type. */
- static FilterGeneric of(Kind kind, int pos, MethodType filterType, MethodType targetType) {
- MethodType entryType = entryType(kind, pos, filterType, targetType);
- if (entryType.generic() != entryType)
- throw newIllegalArgumentException("must be generic: "+entryType);
- MethodTypeImpl form = MethodTypeImpl.of(entryType);
- FilterGeneric filterGen = form.filterGeneric;
- if (filterGen == null)
- form.filterGeneric = filterGen = new FilterGeneric(entryType);
- return filterGen;
- }
-
- public String toString() {
- return "FilterGeneric/"+entryType;
- }
-
- static MethodType targetType(MethodType entryType, Kind kind, int pos, MethodType filterType) {
- MethodType type = entryType;
- switch (kind) {
- case value:
- case flyby:
- break; // no change
- case fold:
- type = type.insertParameterTypes(0, filterType.returnType());
- break;
- case collect:
- type = type.dropParameterTypes(pos, type.parameterCount());
- type = type.insertParameterTypes(pos, filterType.returnType());
- break;
- default:
- throw new InternalError();
- }
- return type;
- }
-
- static MethodType entryType(Kind kind, int pos, MethodType filterType, MethodType targetType) {
- MethodType type = targetType;
- switch (kind) {
- case value:
- case flyby:
- break; // no change
- case fold:
- type = type.dropParameterTypes(0, 1);
- break;
- case collect:
- type = type.dropParameterTypes(pos, pos+1);
- type = type.insertParameterTypes(pos, filterType.parameterList());
- break;
- default:
- throw new InternalError();
- }
- return type;
- }
-
- /* Create an adapter that handles spreading calls for the given type. */
- static Adapter findAdapter(MethodType entryType, Kind kind, int pos) {
- int argc = entryType.parameterCount();
- String cname0 = "F"+argc;
- String cname1 = "F"+argc+kind.key;
- String[] cnames = { cname0, cname1 };
- String iname = kind.invokerName(pos);
- // e.g., F5; invoke_C3
- for (String cname : cnames) {
- Class extends Adapter> acls = Adapter.findSubClass(cname);
- if (acls == null) continue;
- // see if it has the required invoke method
- MethodHandle entryPoint = null;
- try {
- entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
- } catch (ReflectiveOperationException ex) {
- }
- if (entryPoint == null) continue;
- Constructor extends Adapter> ctor = null;
- try {
- ctor = acls.getDeclaredConstructor(MethodHandle.class);
- } catch (NoSuchMethodException ex) {
- } catch (SecurityException ex) {
- }
- if (ctor == null) continue;
- try {
- // Produce an instance configured as a prototype.
- return ctor.newInstance(entryPoint);
- } catch (IllegalArgumentException ex) {
- } catch (InvocationTargetException wex) {
- Throwable ex = wex.getTargetException();
- if (ex instanceof Error) throw (Error)ex;
- if (ex instanceof RuntimeException) throw (RuntimeException)ex;
- } catch (InstantiationException ex) {
- } catch (IllegalAccessException ex) {
- }
- }
- return null;
- }
-
- static Adapter buildAdapterFromBytecodes(MethodType entryType, Kind kind, int pos) {
- throw new UnsupportedOperationException("NYI");
- }
-
- /**
- * This adapter takes some untyped arguments, and returns an untyped result.
- * Internally, it applies the invoker to the target, which causes the
- * objects to be unboxed; the result is a raw type in L/I/J/F/D.
- * This result is passed to convert, which is responsible for
- * converting the raw result into a boxed object.
- * The invoker is kept separate from the target because it can be
- * generated once per type erasure family, and reused across adapters.
- */
- static abstract class Adapter extends BoundMethodHandle {
- protected final MethodHandle filter; // transforms one or more arguments
- protected final MethodHandle target; // ultimate target
-
- @Override
- public String toString() {
- return MethodHandleImpl.addTypeString(target, this);
- }
-
- protected boolean isPrototype() { return target == null; }
- protected Adapter(MethodHandle entryPoint) {
- this(entryPoint, entryPoint, null);
- assert(isPrototype());
- }
- protected MethodHandle prototypeEntryPoint() {
- if (!isPrototype()) throw new InternalError();
- return filter;
- }
-
- protected Adapter(MethodHandle entryPoint,
- MethodHandle filter, MethodHandle target) {
- super(Access.TOKEN, entryPoint);
- this.filter = filter;
- this.target = target;
- }
-
- /** Make a copy of self, with new fields. */
- protected abstract Adapter makeInstance(MethodHandle entryPoint,
- MethodHandle filter, MethodHandle target);
- // { return new ThisType(entryPoint, filter, target); }
-
- static private final String CLASS_PREFIX; // "sun.dyn.FilterGeneric$"
- static {
- String aname = Adapter.class.getName();
- String sname = Adapter.class.getSimpleName();
- if (!aname.endsWith(sname)) throw new InternalError();
- CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
- }
- /** Find a sibing class of Adapter. */
- static Class extends Adapter> findSubClass(String name) {
- String cname = Adapter.CLASS_PREFIX + name;
- try {
- return Class.forName(cname).asSubclass(Adapter.class);
- } catch (ClassNotFoundException ex) {
- return null;
- } catch (ClassCastException ex) {
- return null;
- }
- }
- }
-
- static enum Kind {
- value('V'), // filter and replace Nth argument value
- fold('F'), // fold first N arguments, prepend result
- collect('C'), // collect last N arguments, replace with result
- flyby('Y'), // reify entire argument list, filter, pass to target
- LIMIT('?');
- static final int COUNT = LIMIT.ordinal();
-
- final char key;
- Kind(char key) { this.key = key; }
- String invokerName(int pos) { return "invoke_"+key+""+pos; }
- int invokerIndex(int pos) { return pos * COUNT + ordinal(); }
- }
-
- /* generated classes follow this pattern:
- static class F1X extends Adapter {
- protected F1X(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F1X(MethodHandle e, MethodHandle f, MethodHandle t)
- { super(e, f, t); }
- protected F1X makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
- { return new F1X(e, f, t); }
- protected Object invoke_V0(Object a0) { return target.invokeExact(filter.invokeExact(a0)); }
- protected Object invoke_F0(Object a0) { return target.invokeExact(filter.invokeExact(), a0); }
- protected Object invoke_F1(Object a0) { return target.invokeExact(filter.invokeExact(a0), a0); }
- protected Object invoke_C0(Object a0) { return target.invokeExact(filter.invokeExact(a0)); }
- protected Object invoke_C1(Object a0) { return target.invokeExact(a0, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0) { Object[] av = { a0 };
- filter.invokeExact(av); return target.invokeExact(av[0]); }
- }
- static class F2X extends Adapter {
- protected F2X(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F2X(MethodHandle e, MethodHandle f, MethodHandle t)
- { super(e, f, t); }
- protected F2X makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
- { return new F2X(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0), a1); }
- protected Object invoke_V1(Object a0, Object a1) { return target.invokeExact(a0, filter.invokeExact(a1)); }
- protected Object invoke_F0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(), a0, a1); }
- protected Object invoke_F1(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0), a0, a1); }
- protected Object invoke_F2(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0, a1), a0, a1); }
- protected Object invoke_C0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0, a1)); }
- protected Object invoke_C1(Object a0, Object a1) { return target.invokeExact(a0, filter.invokeExact(a1)); }
- protected Object invoke_C2(Object a0, Object a1) { return target.invokeExact(a0, a1, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1) { Object[] av = { a0, a1 };
- filter.invokeExact(av); return target.invokeExact(av[0], av[1]); }
- }
- // */
-
- // This one is written by hand:
- static class F0 extends Adapter {
- protected F0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F0(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F0 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F0(e, f, t); }
- protected Object invoke_F0() throws Throwable {
- return target.invokeExact(filter.invokeExact()); }
- protected Object invoke_C0() throws Throwable {
- return target.invokeExact(filter.invokeExact()); }
- static final Object[] NO_ARGS = { };
- protected Object invoke_Y0() throws Throwable {
- filter.invokeExact(NO_ARGS); // make the flyby
- return target.invokeExact(); }
- }
-
-/*
- : SHELL; n=FilterGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -ea -cp . genclasses | sed 's| *[/]/ *$||') >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
-//{{{
-import java.util.*;
-class genclasses {
- static String[][] TEMPLATES = { {
- "@for@ N=1..20",
- " //@each-cat@",
- " static class @cat@ extends Adapter {",
- " protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
- " protected @cat@(MethodHandle e, MethodHandle f, MethodHandle t) {",
- " super(e, f, t); }",
- " protected @cat@ makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {",
- " return new @cat@(e, f, t); }",
- " //@each-P@",
- " protected Object invoke_V@P@(@Tvav@) throws Throwable {",
- " return target.invokeExact(@a0_@@Psp@filter.invokeExact(a@P@)@_aN@); }",
- " //@end-P@",
- " //@each-P@",
- " protected Object invoke_F@P@(@Tvav@) throws Throwable {",
- " return target.invokeExact(filter.invokeExact(@a0@),",
- " @av@); }",
- " //@end-P@",
- " protected Object invoke_F@N@(@Tvav@) throws Throwable {",
- " return target.invokeExact(filter.invokeExact(@av@),",
- " @av@); }",
- " //@each-P@",
- " protected Object invoke_C@P@(@Tvav@) throws Throwable {",
- " return target.invokeExact(@a0_@filter.invokeExact(a@P@@_aN@)); }",
- " //@end-P@",
- " protected Object invoke_C@N@(@Tvav@) throws Throwable {",
- " return target.invokeExact(@av@, filter.invokeExact()); }",
- " protected Object invoke_Y0(@Tvav@) throws Throwable {",
- " Object[] av = { @av@ };",
- " filter.invokeExact(av); // make the flyby",
- " return target.invokeExact(@av[i]@); }",
- " }",
- } };
- static final String NEWLINE_INDENT = " //\n ";
- enum VAR {
- cat, N, P, Tvav, av, a0, a0_, _aN, Psp, av_i_;
- public final String pattern = "@"+toString().replace('_','.')+"@";
- public String binding = toString();
- static void makeBindings(boolean topLevel, int inargs, int pos) {
- assert(-1 <= pos && pos < inargs);
- VAR.cat.binding = "F"+inargs;
- VAR.N.binding = String.valueOf(inargs); // incoming arg count
- VAR.P.binding = String.valueOf(pos); // selected arg position
- String[] av = new String[inargs];
- String[] Tvav = new String[inargs];
- String[] av_i_ = new String[inargs];
- for (int i = 0; i < inargs; i++) {
- av[i] = arg(i);
- av_i_[i] = "av["+i+"]";
- String spc = "";
- if (i > 0 && i % 4 == 0) spc = NEWLINE_INDENT+(pos>9?" ":"")+" ";
- Tvav[i] = spc+param("Object", av[i]);
- }
- VAR.av.binding = comma(av);
- VAR.av_i_.binding = comma(av_i_);
- VAR.Tvav.binding = comma(Tvav);
- if (pos >= 0) {
- VAR.Psp.binding = (pos > 0 && pos % 10 == 0) ? NEWLINE_INDENT : "";
- String[] a0 = new String[pos];
- String[] aN = new String[inargs - (pos+1)];
- for (int i = 0; i < pos; i++) {
- String spc = "";
- if (i > 0 && i % 10 == 0) spc = NEWLINE_INDENT;
- a0[i] = spc+av[i];
- }
- VAR.a0.binding = comma(a0);
- VAR.a0_.binding = comma(a0, ", ");
- for (int i = pos+1; i < inargs; i++) {
- String spc = "";
- if (i > 0 && i % 10 == 0) spc = NEWLINE_INDENT;
- aN[i - (pos+1)] = spc+av[i];
- }
- VAR._aN.binding = comma(", ", aN);
- }
- }
- static String arg(int i) { return "a"+i; }
- static String param(String t, String a) { return t+" "+a; }
- static String comma(String[] v) { return comma(v, ""); }
- static String comma(String[] v, String sep) { return comma("", v, sep); }
- static String comma(String sep, String[] v) { return comma(sep, v, ""); }
- static String comma(String sep1, String[] v, String sep2) {
- if (v.length == 0) return "";
- String res = v[0];
- for (int i = 1; i < v.length; i++) res += ", "+v[i];
- return sep1 + res + sep2;
- }
- static String transform(String string) {
- for (VAR var : values())
- string = string.replaceAll(var.pattern, var.binding);
- return string;
- }
- }
- static String[] stringsIn(String[] strings, int beg, int end) {
- return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
- }
- static String[] stringsBefore(String[] strings, int pos) {
- return stringsIn(strings, 0, pos);
- }
- static String[] stringsAfter(String[] strings, int pos) {
- return stringsIn(strings, pos, strings.length);
- }
- static int indexAfter(String[] strings, int pos, String tag) {
- return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
- }
- static int indexBefore(String[] strings, int pos, String tag) {
- for (int i = pos, end = strings.length; ; i++) {
- if (i == end || strings[i].endsWith(tag)) return i;
- }
- }
- static int MIN_ARITY, MAX_ARITY;
- public static void main(String... av) {
- for (String[] template : TEMPLATES) {
- int forLinesLimit = indexBefore(template, 0, "@each-cat@");
- String[] forLines = stringsBefore(template, forLinesLimit);
- template = stringsAfter(template, forLinesLimit);
- for (String forLine : forLines)
- expandTemplate(forLine, template);
- }
- }
- static void expandTemplate(String forLine, String[] template) {
- String[] params = forLine.split("[^0-9]+");
- if (params[0].length() == 0) params = stringsAfter(params, 1);
- System.out.println("//params="+Arrays.asList(params));
- int pcur = 0;
- MIN_ARITY = Integer.valueOf(params[pcur++]);
- MAX_ARITY = Integer.valueOf(params[pcur++]);
- if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
- for (int inargs = MIN_ARITY; inargs <= MAX_ARITY; inargs++) {
- expandTemplate(template, true, inargs, -1);
- }
- }
- static void expandTemplate(String[] template, boolean topLevel, int inargs, int pos) {
- VAR.makeBindings(topLevel, inargs, pos);
- for (int i = 0; i < template.length; i++) {
- String line = template[i];
- if (line.endsWith("@each-cat@")) {
- // ignore
- } else if (line.endsWith("@each-P@")) {
- int blockEnd = indexAfter(template, i, "@end-P@");
- String[] block = stringsIn(template, i+1, blockEnd-1);
- for (int pos1 = Math.max(0,pos); pos1 < inargs; pos1++)
- expandTemplate(block, false, inargs, pos1);
- VAR.makeBindings(topLevel, inargs, pos);
- i = blockEnd-1; continue;
- } else {
- System.out.println(VAR.transform(line));
- }
- }
- }
-}
-//}}} */
-//params=[1, 20]
- static class F1 extends Adapter {
- protected F1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F1(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F1 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F1(e, f, t); }
- protected Object invoke_V0(Object a0) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0)); }
- protected Object invoke_F0(Object a0) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0); }
- protected Object invoke_F1(Object a0) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0); }
- protected Object invoke_C0(Object a0) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0)); }
- protected Object invoke_C1(Object a0) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0) throws Throwable {
- Object[] av = { a0 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0]); }
- }
- static class F2 extends Adapter {
- protected F2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F2(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F2 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F2(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1); }
- protected Object invoke_V1(Object a0, Object a1) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1)); }
- protected Object invoke_F0(Object a0, Object a1) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1); }
- protected Object invoke_F1(Object a0, Object a1) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1); }
- protected Object invoke_F2(Object a0, Object a1) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1); }
- protected Object invoke_C0(Object a0, Object a1) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1)); }
- protected Object invoke_C1(Object a0, Object a1) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1)); }
- protected Object invoke_C2(Object a0, Object a1) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1) throws Throwable {
- Object[] av = { a0, a1 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1]); }
- }
- static class F3 extends Adapter {
- protected F3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F3(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F3 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F3(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2); }
- protected Object invoke_V1(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2); }
- protected Object invoke_V2(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2); }
- protected Object invoke_F1(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2); }
- protected Object invoke_F2(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2); }
- protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2); }
- protected Object invoke_C0(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2) throws Throwable {
- Object[] av = { a0, a1, a2 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2]); }
- }
- static class F4 extends Adapter {
- protected F4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F4(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F4 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F4(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- Object[] av = { a0, a1, a2, a3 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3]); }
- }
- static class F5 extends Adapter {
- protected F5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F5(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F5 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F5(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4]); }
- }
- static class F6 extends Adapter {
- protected F6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F6(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F6 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F6(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5]); }
- }
- static class F7 extends Adapter {
- protected F7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F7(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F7 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F7(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6]); }
- }
- static class F8 extends Adapter {
- protected F8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F8(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F8 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F8(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7]); }
- }
- static class F9 extends Adapter {
- protected F9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F9(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F9 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F9(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8]); }
- }
- static class F10 extends Adapter {
- protected F10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F10(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F10 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F10(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9]); }
- }
- static class F11 extends Adapter {
- protected F11(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F11(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F11 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F11(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10]); }
- }
- static class F12 extends Adapter {
- protected F12(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F12(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F12 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F12(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11]); }
- }
- static class F13 extends Adapter {
- protected F13(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F13(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F13 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F13(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11, a12); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11, a12); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11, a12); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11, a12); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11, a12); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11, a12); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11, a12); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11, a12); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11), a12); }
- protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11, a12)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11, a12)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11, a12)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12)); }
- protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12]); }
- }
- static class F14 extends Adapter {
- protected F14(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F14(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F14 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F14(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11, a12, a13); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11, a12, a13); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11, a12, a13); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11, a12, a13); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11, a12, a13); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11, a12, a13); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11, a12, a13); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11), a12, a13); }
- protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12), a13); }
- protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11, a12, a13)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11, a12, a13)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12, a13)); }
- protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13)); }
- protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13]); }
- }
- static class F15 extends Adapter {
- protected F15(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F15(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F15 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F15(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11, a12, a13, a14); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11, a12, a13, a14); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11, a12, a13, a14); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11), a12, a13, a14); }
- protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12), a13, a14); }
- protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13), a14); }
- protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11, a12, a13, a14)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11, a12, a13, a14)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12, a13, a14)); }
- protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13, a14)); }
- protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14)); }
- protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14]); }
- }
- static class F16 extends Adapter {
- protected F16(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F16(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F16 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F16(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11, a12, a13, a14, a15); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11, a12, a13, a14, a15); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11), a12, a13, a14, a15); }
- protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12), a13, a14, a15); }
- protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13), a14, a15); }
- protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14), a15); }
- protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11, a12, a13, a14, a15)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12, a13, a14, a15)); }
- protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13, a14, a15)); }
- protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14, a15)); }
- protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15)); }
- protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15]); }
- }
- static class F17 extends Adapter {
- protected F17(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F17(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F17 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F17(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11, a12, a13, a14, a15, a16); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11), a12, a13, a14, a15, a16); }
- protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12), a13, a14, a15, a16); }
- protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13), a14, a15, a16); }
- protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14), a15, a16); }
- protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15), a16); }
- protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, filter.invokeExact(a16)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11, a12, a13, a14, a15, a16)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12, a13, a14, a15, a16)); }
- protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13, a14, a15, a16)); }
- protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14, a15, a16)); }
- protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15, a16)); }
- protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, filter.invokeExact(a16)); }
- protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16]); }
- }
- static class F18 extends Adapter {
- protected F18(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F18(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F18 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F18(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17); }
- protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17); }
- protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17); }
- protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17); }
- protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17); }
- protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17); }
- protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17)); }
- protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17)); }
- protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17)); }
- protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17)); }
- protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17)); }
- protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17)); }
- protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17]); }
- }
- static class F19 extends Adapter {
- protected F19(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F19(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F19 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F19(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17, a18); }
- protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17, a18); }
- protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17, a18); }
- protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17, a18); }
- protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17, a18); }
- protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17), a18); }
- protected Object invoke_V18(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_F19(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17, a18)); }
- protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17, a18)); }
- protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17, a18)); }
- protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17, a18)); }
- protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17, a18)); }
- protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18)); }
- protected Object invoke_C19(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17], av[18]); }
- }
- static class F20 extends Adapter {
- protected F20(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected F20(MethodHandle e, MethodHandle f, MethodHandle t) {
- super(e, f, t); }
- protected F20 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
- return new F20(e, f, t); }
- protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17, a18, a19); }
- protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17, a18, a19); }
- protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17, a18, a19); }
- protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17, a18, a19); }
- protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17), a18, a19); }
- protected Object invoke_V18(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18), a19); }
- protected Object invoke_V19(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact(a19)); }
- protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F19(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_F20(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19),
- a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
- protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17, a18, a19)); }
- protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17, a18, a19)); }
- protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17, a18, a19)); }
- protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17, a18, a19)); }
- protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18, a19)); }
- protected Object invoke_C19(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact(a19)); }
- protected Object invoke_C20(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, filter.invokeExact()); }
- protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
- Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9, Object a10, Object a11,
- Object a12, Object a13, Object a14, Object a15,
- Object a16, Object a17, Object a18, Object a19) throws Throwable {
- Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19 };
- filter.invokeExact(av); // make the flyby
- return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17], av[18], av[19]); }
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/FilterOneArgument.java
--- a/jdk/src/share/classes/sun/dyn/FilterOneArgument.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2008, 2010, 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.
- */
-
-package sun.dyn;
-
-import java.dyn.*;
-import static sun.dyn.MemberName.uncaughtException;
-
-/**
- * Unary function composition, useful for many small plumbing jobs.
- * The invoke method takes a single reference argument, and returns a reference
- * Internally, it first calls the {@code filter} method on the argument,
- * Making up the difference between the raw method type and the
- * final method type is the responsibility of a JVM-level adapter.
- * @author jrose
- */
-public class FilterOneArgument extends BoundMethodHandle {
- protected final MethodHandle filter; // Object -> Object
- protected final MethodHandle target; // Object -> Object
-
- @Override
- public String toString() {
- return target.toString();
- }
-
- protected Object invoke(Object argument) throws Throwable {
- Object filteredArgument = filter.invokeExact(argument);
- return target.invokeExact(filteredArgument);
- }
-
- private static final MethodHandle INVOKE;
- static {
- try {
- INVOKE =
- MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke",
- MethodType.genericMethodType(1));
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- }
-
- protected FilterOneArgument(MethodHandle filter, MethodHandle target) {
- super(Access.TOKEN, INVOKE);
- this.filter = filter;
- this.target = target;
- }
-
- public static MethodHandle make(MethodHandle filter, MethodHandle target) {
- if (filter == null) return target;
- if (target == null) return filter;
- return new FilterOneArgument(filter, target);
- }
-
-// MethodHandle make(MethodHandle filter1, MethodHandle filter2, MethodHandle target) {
-// MethodHandle filter = make(filter1, filter2);
-// return make(filter, target);
-// }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/FromGeneric.java
--- a/jdk/src/share/classes/sun/dyn/FromGeneric.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,629 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package sun.dyn;
-
-import java.dyn.*;
-import java.lang.reflect.*;
-import sun.dyn.util.*;
-import static sun.dyn.MethodTypeImpl.invokers;
-
-/**
- * Adapters which mediate between incoming calls which are generic
- * and outgoing calls which are not. Any call can be represented generically
- * boxing up its arguments, and (on return) unboxing the return value.
- *
- * A call is "generic" (in MethodHandle terms) if its MethodType features
- * only Object arguments. A non-generic call therefore features
- * primitives and/or reference types other than Object.
- * An adapter has types for its incoming and outgoing calls.
- * The incoming call type is simply determined by the adapter's type
- * (the MethodType it presents to callers). The outgoing call type
- * is determined by the adapter's target (a MethodHandle that the adapter
- * either binds internally or else takes as a leading argument).
- * (To stretch the term, adapter-like method handles may have multiple
- * targets or be polymorphic across multiple call types.)
- * @author jrose
- */
-class FromGeneric {
- // type for the outgoing call (may have primitives, etc.)
- private final MethodType targetType;
- // type of the outgoing call internal to the adapter
- private final MethodType internalType;
- // prototype adapter (clone and customize for each new target!)
- private final Adapter adapter;
- // entry point for adapter (Adapter mh, a...) => ...
- private final MethodHandle entryPoint;
- // unboxing invoker of type (MH, Object**N) => raw return value
- // it makes up the difference of internalType => targetType
- private final MethodHandle unboxingInvoker;
- // conversion which boxes a the target's raw return value
- private final MethodHandle returnConversion;
-
- /** Compute and cache information common to all unboxing adapters
- * that can call out to targets of the erasure-family of the given erased type.
- */
- private FromGeneric(MethodType targetType) {
- this.targetType = targetType;
- MethodType internalType0;
- // the target invoker will generally need casts on reference arguments
- Adapter ad = findAdapter(internalType0 = targetType.erase());
- if (ad != null) {
- // Immediate hit to exactly the adapter we want,
- // with no monkeying around with primitive types.
- this.internalType = internalType0;
- this.adapter = ad;
- this.entryPoint = ad.prototypeEntryPoint();
- this.returnConversion = computeReturnConversion(targetType, internalType0);
- this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
- return;
- }
-
- // outgoing primitive arguments will be wrapped; unwrap them
- MethodType primsAsObj = MethodTypeImpl.of(targetType).primArgsAsBoxes();
- MethodType objArgsRawRet = MethodTypeImpl.of(primsAsObj).primsAsInts();
- if (objArgsRawRet != targetType)
- ad = findAdapter(internalType0 = objArgsRawRet);
- if (ad == null) {
- ad = buildAdapterFromBytecodes(internalType0 = targetType);
- }
- this.internalType = internalType0;
- this.adapter = ad;
- MethodType tepType = targetType.insertParameterTypes(0, adapter.getClass());
- this.entryPoint = ad.prototypeEntryPoint();
- this.returnConversion = computeReturnConversion(targetType, internalType0);
- this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
- }
-
- /**
- * The typed target will be called according to targetType.
- * The adapter code will in fact see the raw result from internalType,
- * and must box it into an object. Produce a converter for this.
- */
- private static MethodHandle computeReturnConversion(
- MethodType targetType, MethodType internalType) {
- Class> tret = targetType.returnType();
- Class> iret = internalType.returnType();
- Wrapper wrap = Wrapper.forBasicType(tret);
- if (!iret.isPrimitive()) {
- assert(iret == Object.class);
- return ValueConversions.identity();
- } else if (wrap.primitiveType() == iret) {
- return ValueConversions.box(wrap, false);
- } else {
- assert(tret == double.class ? iret == long.class : iret == int.class);
- return ValueConversions.boxRaw(wrap, false);
- }
- }
-
- /**
- * The typed target will need an exact invocation point; provide it here.
- * The adapter will possibly need to make a slightly different call,
- * so adapt the invoker. This way, the logic for making up the
- * difference between what the adapter can call and what the target
- * needs can be cached once per type.
- */
- private static MethodHandle computeUnboxingInvoker(
- MethodType targetType, MethodType internalType) {
- // All the adapters we have here have reference-untyped internal calls.
- assert(internalType == internalType.erase());
- MethodHandle invoker = invokers(targetType).exactInvoker();
- // cast all narrow reference types, unbox all primitive arguments:
- MethodType fixArgsType = internalType.changeReturnType(targetType.returnType());
- MethodHandle fixArgs = AdapterMethodHandle.convertArguments(Access.TOKEN,
- invoker, Invokers.invokerType(fixArgsType),
- invoker.type(), null);
- if (fixArgs == null)
- throw new InternalError("bad fixArgs");
- // reinterpret the calling sequence as raw:
- MethodHandle retyper = AdapterMethodHandle.makeRetypeRaw(Access.TOKEN,
- Invokers.invokerType(internalType), fixArgs);
- if (retyper == null)
- throw new InternalError("bad retyper");
- return retyper;
- }
-
- Adapter makeInstance(MethodHandle typedTarget) {
- MethodType type = typedTarget.type();
- if (type == targetType) {
- return adapter.makeInstance(entryPoint, unboxingInvoker, returnConversion, typedTarget);
- }
- // my erased-type is not exactly the same as the desired type
- assert(type.erase() == targetType); // else we are busted
- MethodHandle invoker = computeUnboxingInvoker(type, internalType);
- return adapter.makeInstance(entryPoint, invoker, returnConversion, typedTarget);
- }
-
- /** Build an adapter of the given generic type, which invokes typedTarget
- * on the incoming arguments, after unboxing as necessary.
- * The return value is boxed if necessary.
- * @param genericType the required type of the result
- * @param typedTarget the target
- * @return an adapter method handle
- */
- public static MethodHandle make(MethodHandle typedTarget) {
- MethodType type = typedTarget.type();
- if (type == type.generic()) return typedTarget;
- return FromGeneric.of(type).makeInstance(typedTarget);
- }
-
- /** Return the adapter information for this type's erasure. */
- static FromGeneric of(MethodType type) {
- MethodTypeImpl form = MethodTypeImpl.of(type);
- FromGeneric fromGen = form.fromGeneric;
- if (fromGen == null)
- form.fromGeneric = fromGen = new FromGeneric(form.erasedType());
- return fromGen;
- }
-
- public String toString() {
- return "FromGeneric"+targetType;
- }
-
- /* Create an adapter that handles spreading calls for the given type. */
- static Adapter findAdapter(MethodType internalType) {
- MethodType entryType = internalType.generic();
- MethodTypeImpl form = MethodTypeImpl.of(internalType);
- Class> rtype = internalType.returnType();
- int argc = form.parameterCount();
- int lac = form.longPrimitiveParameterCount();
- int iac = form.primitiveParameterCount() - lac;
- String intsAndLongs = (iac > 0 ? "I"+iac : "")+(lac > 0 ? "J"+lac : "");
- String rawReturn = String.valueOf(Wrapper.forPrimitiveType(rtype).basicTypeChar());
- String cname0 = rawReturn + argc;
- String cname1 = "A" + argc;
- String[] cnames = { cname0+intsAndLongs, cname0, cname1+intsAndLongs, cname1 };
- String iname = "invoke_"+cname0+intsAndLongs;
- // e.g., D5I2, D5, L5I2, L5; invoke_D5
- for (String cname : cnames) {
- Class extends Adapter> acls = Adapter.findSubClass(cname);
- if (acls == null) continue;
- // see if it has the required invoke method
- MethodHandle entryPoint = null;
- try {
- entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
- } catch (ReflectiveOperationException ex) {
- }
- if (entryPoint == null) continue;
- Constructor extends Adapter> ctor = null;
- try {
- ctor = acls.getDeclaredConstructor(MethodHandle.class);
- } catch (NoSuchMethodException ex) {
- } catch (SecurityException ex) {
- }
- if (ctor == null) continue;
- try {
- // Produce an instance configured as a prototype.
- return ctor.newInstance(entryPoint);
- } catch (IllegalArgumentException ex) {
- } catch (InvocationTargetException wex) {
- Throwable ex = wex.getTargetException();
- if (ex instanceof Error) throw (Error)ex;
- if (ex instanceof RuntimeException) throw (RuntimeException)ex;
- } catch (InstantiationException ex) {
- } catch (IllegalAccessException ex) {
- }
- }
- return null;
- }
-
- static Adapter buildAdapterFromBytecodes(MethodType internalType) {
- throw new UnsupportedOperationException("NYI");
- }
-
- /**
- * This adapter takes some untyped arguments, and returns an untyped result.
- * Internally, it applies the invoker to the target, which causes the
- * objects to be unboxed; the result is a raw type in L/I/J/F/D.
- * This result is passed to convert, which is responsible for
- * converting the raw result into a boxed object.
- * The invoker is kept separate from the target because it can be
- * generated once per type erasure family, and reused across adapters.
- */
- static abstract class Adapter extends BoundMethodHandle {
- /*
- * class X<> extends Adapter {
- * (MH, Object**N)=>raw(R) invoker;
- * (any**N)=>R target;
- * raw(R)=>Object convert;
- * Object invoke(Object**N a) = convert(invoker(target, a...))
- * }
- */
- protected final MethodHandle invoker; // (MH, Object**N) => raw(R)
- protected final MethodHandle convert; // raw(R) => Object
- protected final MethodHandle target; // (any**N) => R
-
- @Override
- public String toString() {
- return MethodHandleImpl.addTypeString(target, this);
- }
-
- protected boolean isPrototype() { return target == null; }
- protected Adapter(MethodHandle entryPoint) {
- this(entryPoint, null, entryPoint, null);
- assert(isPrototype());
- }
- protected MethodHandle prototypeEntryPoint() {
- if (!isPrototype()) throw new InternalError();
- return convert;
- }
-
- protected Adapter(MethodHandle entryPoint,
- MethodHandle invoker, MethodHandle convert, MethodHandle target) {
- super(Access.TOKEN, entryPoint);
- this.invoker = invoker;
- this.convert = convert;
- this.target = target;
- }
-
- /** Make a copy of self, with new fields. */
- protected abstract Adapter makeInstance(MethodHandle entryPoint,
- MethodHandle invoker, MethodHandle convert, MethodHandle target);
- // { return new ThisType(entryPoint, convert, target); }
-
- /// Conversions on the value returned from the target.
- protected Object convert_L(Object result) throws Throwable { return convert.invokeExact(result); }
- protected Object convert_I(int result) throws Throwable { return convert.invokeExact(result); }
- protected Object convert_J(long result) throws Throwable { return convert.invokeExact(result); }
- protected Object convert_F(float result) throws Throwable { return convert.invokeExact(result); }
- protected Object convert_D(double result) throws Throwable { return convert.invokeExact(result); }
-
- static private final String CLASS_PREFIX; // "sun.dyn.FromGeneric$"
- static {
- String aname = Adapter.class.getName();
- String sname = Adapter.class.getSimpleName();
- if (!aname.endsWith(sname)) throw new InternalError();
- CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
- }
- /** Find a sibing class of Adapter. */
- static Class extends Adapter> findSubClass(String name) {
- String cname = Adapter.CLASS_PREFIX + name;
- try {
- return Class.forName(cname).asSubclass(Adapter.class);
- } catch (ClassNotFoundException ex) {
- return null;
- } catch (ClassCastException ex) {
- return null;
- }
- }
- }
-
- /* generated classes follow this pattern:
- static class xA2 extends Adapter {
- protected xA2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected xA2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected xA2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new xA2(e, i, c, t); }
- protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1)); }
- protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1)); }
- protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1)); }
- protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1)); }
- protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1)); }
- }
- // */
-
-/*
-: SHELL; n=FromGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
-//{{{
-import java.util.*;
-class genclasses {
- static String[] TYPES = { "Object", "int ", "long ", "float ", "double" };
- static String[] WRAPS = { " ", "(Integer)", "(Long) ", "(Float) ", "(Double) " };
- static String[] TCHARS = { "L", "I", "J", "F", "D", "A" };
- static String[][] TEMPLATES = { {
- "@for@ arity=0..10 rcat<=4 nrefs<=99 nints=0 nlongs=0",
- " //@each-cat@",
- " static class @cat@ extends Adapter {",
- " protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
- " protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
- " { super(e, i, c, t); }",
- " protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
- " { return new @cat@(e, i, c, t); }",
- " //@each-R@",
- " protected Object invoke_@catN@(@Tvav@) throws Throwable { return convert_@Rc@((@R@)@W@invoker.invokeExact(target@av@)); }",
- " //@end-R@",
- " }",
- } };
- static final String NEWLINE_INDENT = "\n ";
- enum VAR {
- cat, catN, R, Rc, W, av, Tvav, Ovav;
- public final String pattern = "@"+toString().replace('_','.')+"@";
- public String binding;
- static void makeBindings(boolean topLevel, int rcat, int nrefs, int nints, int nlongs) {
- int nargs = nrefs + nints + nlongs;
- if (topLevel)
- VAR.cat.binding = catstr(ALL_RETURN_TYPES ? TYPES.length : rcat, nrefs, nints, nlongs);
- VAR.catN.binding = catstr(rcat, nrefs, nints, nlongs);
- VAR.R.binding = TYPES[rcat];
- VAR.Rc.binding = TCHARS[rcat];
- VAR.W.binding = WRAPS[rcat];
- String[] Tv = new String[nargs];
- String[] av = new String[nargs];
- String[] Tvav = new String[nargs];
- String[] Ovav = new String[nargs];
- for (int i = 0; i < nargs; i++) {
- int tcat = (i < nrefs) ? 0 : (i < nrefs + nints) ? 1 : 2;
- Tv[i] = TYPES[tcat];
- av[i] = arg(i);
- Tvav[i] = param(Tv[i], av[i]);
- Ovav[i] = param("Object", av[i]);
- }
- VAR.av.binding = comma(", ", av);
- VAR.Tvav.binding = comma(Tvav);
- VAR.Ovav.binding = comma(Ovav);
- }
- static String arg(int i) { return "a"+i; }
- static String param(String t, String a) { return t+" "+a; }
- static String comma(String[] v) { return comma("", v); }
- static String comma(String sep, String[] v) {
- if (v.length == 0) return "";
- String res = sep+v[0];
- for (int i = 1; i < v.length; i++) res += ", "+v[i];
- return res;
- }
- static String transform(String string) {
- for (VAR var : values())
- string = string.replaceAll(var.pattern, var.binding);
- return string;
- }
- }
- static String[] stringsIn(String[] strings, int beg, int end) {
- return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
- }
- static String[] stringsBefore(String[] strings, int pos) {
- return stringsIn(strings, 0, pos);
- }
- static String[] stringsAfter(String[] strings, int pos) {
- return stringsIn(strings, pos, strings.length);
- }
- static int indexAfter(String[] strings, int pos, String tag) {
- return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
- }
- static int indexBefore(String[] strings, int pos, String tag) {
- for (int i = pos, end = strings.length; ; i++) {
- if (i == end || strings[i].endsWith(tag)) return i;
- }
- }
- static int MIN_ARITY, MAX_ARITY, MAX_RCAT, MAX_REFS, MAX_INTS, MAX_LONGS;
- static boolean ALL_ARG_TYPES, ALL_RETURN_TYPES;
- static HashSet done = new HashSet();
- public static void main(String... av) {
- for (String[] template : TEMPLATES) {
- int forLinesLimit = indexBefore(template, 0, "@each-cat@");
- String[] forLines = stringsBefore(template, forLinesLimit);
- template = stringsAfter(template, forLinesLimit);
- for (String forLine : forLines)
- expandTemplate(forLine, template);
- }
- }
- static void expandTemplate(String forLine, String[] template) {
- String[] params = forLine.split("[^0-9]+");
- if (params[0].length() == 0) params = stringsAfter(params, 1);
- System.out.println("//params="+Arrays.asList(params));
- int pcur = 0;
- MIN_ARITY = Integer.valueOf(params[pcur++]);
- MAX_ARITY = Integer.valueOf(params[pcur++]);
- MAX_RCAT = Integer.valueOf(params[pcur++]);
- MAX_REFS = Integer.valueOf(params[pcur++]);
- MAX_INTS = Integer.valueOf(params[pcur++]);
- MAX_LONGS = Integer.valueOf(params[pcur++]);
- if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
- if (MAX_RCAT >= TYPES.length) MAX_RCAT = TYPES.length - 1;
- ALL_ARG_TYPES = (indexBefore(template, 0, "@each-Tv@") < template.length);
- ALL_RETURN_TYPES = (indexBefore(template, 0, "@each-R@") < template.length);
- for (int nargs = MIN_ARITY; nargs <= MAX_ARITY; nargs++) {
- for (int rcat = 0; rcat <= MAX_RCAT; rcat++) {
- expandTemplate(template, true, rcat, nargs, 0, 0);
- if (ALL_ARG_TYPES) break;
- expandTemplateForPrims(template, true, rcat, nargs, 1, 1);
- if (ALL_RETURN_TYPES) break;
- }
- }
- }
- static String catstr(int rcat, int nrefs, int nints, int nlongs) {
- int nargs = nrefs + nints + nlongs;
- String cat = TCHARS[rcat] + nargs;
- if (!ALL_ARG_TYPES) cat += (nints==0?"":"I"+nints)+(nlongs==0?"":"J"+nlongs);
- return cat;
- }
- static void expandTemplateForPrims(String[] template, boolean topLevel, int rcat, int nargs, int minints, int minlongs) {
- for (int isLong = 0; isLong <= 1; isLong++) {
- for (int nprims = 1; nprims <= nargs; nprims++) {
- int nrefs = nargs - nprims;
- int nints = ((1-isLong) * nprims);
- int nlongs = (isLong * nprims);
- expandTemplate(template, topLevel, rcat, nrefs, nints, nlongs);
- }
- }
- }
- static void expandTemplate(String[] template, boolean topLevel,
- int rcat, int nrefs, int nints, int nlongs) {
- int nargs = nrefs + nints + nlongs;
- if (nrefs > MAX_REFS || nints > MAX_INTS || nlongs > MAX_LONGS) return;
- VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
- if (topLevel && !done.add(VAR.cat.binding)) {
- System.out.println(" //repeat "+VAR.cat.binding);
- return;
- }
- for (int i = 0; i < template.length; i++) {
- String line = template[i];
- if (line.endsWith("@each-cat@")) {
- // ignore
- } else if (line.endsWith("@each-R@")) {
- int blockEnd = indexAfter(template, i, "@end-R@");
- String[] block = stringsIn(template, i+1, blockEnd-1);
- for (int rcat1 = rcat; rcat1 <= MAX_RCAT; rcat1++)
- expandTemplate(block, false, rcat1, nrefs, nints, nlongs);
- VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
- i = blockEnd-1; continue;
- } else if (line.endsWith("@each-Tv@")) {
- int blockEnd = indexAfter(template, i, "@end-Tv@");
- String[] block = stringsIn(template, i+1, blockEnd-1);
- expandTemplate(block, false, rcat, nrefs, nints, nlongs);
- expandTemplateForPrims(block, false, rcat, nargs, nints+1, nlongs+1);
- VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
- i = blockEnd-1; continue;
- } else {
- System.out.println(VAR.transform(line));
- }
- }
- }
-}
-//}}} */
-//params=[0, 10, 4, 99, 0, 0]
- static class A0 extends Adapter {
- protected A0(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A0(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A0(e, i, c, t); }
- protected Object invoke_L0() throws Throwable { return convert_L((Object)invoker.invokeExact(target)); }
- protected Object invoke_I0() throws Throwable { return convert_I((int) invoker.invokeExact(target)); }
- protected Object invoke_J0() throws Throwable { return convert_J((long) invoker.invokeExact(target)); }
- protected Object invoke_F0() throws Throwable { return convert_F((float) invoker.invokeExact(target)); }
- protected Object invoke_D0() throws Throwable { return convert_D((double)invoker.invokeExact(target)); }
- }
- static class A1 extends Adapter {
- protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A1(e, i, c, t); }
- protected Object invoke_L1(Object a0) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0)); }
- protected Object invoke_I1(Object a0) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0)); }
- protected Object invoke_J1(Object a0) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0)); }
- protected Object invoke_F1(Object a0) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0)); }
- protected Object invoke_D1(Object a0) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0)); }
- }
- static class A2 extends Adapter {
- protected A2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A2(e, i, c, t); }
- protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1)); }
- protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1)); }
- protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1)); }
- protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1)); }
- protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1)); }
- }
- static class A3 extends Adapter {
- protected A3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A3(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A3 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A3(e, i, c, t); }
- protected Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2)); }
- protected Object invoke_I3(Object a0, Object a1, Object a2) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2)); }
- protected Object invoke_J3(Object a0, Object a1, Object a2) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2)); }
- protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2)); }
- protected Object invoke_D3(Object a0, Object a1, Object a2) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2)); }
- }
- static class A4 extends Adapter {
- protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A4(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A4 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A4(e, i, c, t); }
- protected Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3)); }
- protected Object invoke_I4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3)); }
- protected Object invoke_J4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3)); }
- protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3)); }
- protected Object invoke_D4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3)); }
- }
- static class A5 extends Adapter {
- protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A5(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A5 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A5(e, i, c, t); }
- protected Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
- protected Object invoke_I5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
- protected Object invoke_J5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
- protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
- protected Object invoke_D5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
- }
- static class A6 extends Adapter {
- protected A6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A6(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A6 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A6(e, i, c, t); }
- protected Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_I6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_J6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
- protected Object invoke_D6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
- }
- static class A7 extends Adapter {
- protected A7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A7(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A7 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A7(e, i, c, t); }
- protected Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_I7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_J7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
- protected Object invoke_D7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
- }
- static class A8 extends Adapter {
- protected A8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A8(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A8 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A8(e, i, c, t); }
- protected Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_I8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_J8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- protected Object invoke_D8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
- }
- static class A9 extends Adapter {
- protected A9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A9(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A9 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A9(e, i, c, t); }
- protected Object invoke_L9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_I9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_J9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- protected Object invoke_D9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
- }
- static class A10 extends Adapter {
- protected A10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
- protected A10(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { super(e, i, c, t); }
- protected A10 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
- { return new A10(e, i, c, t); }
- protected Object invoke_L10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_I10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_I((int) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_J10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_J((long) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- protected Object invoke_D10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/InvokeGeneric.java
--- a/jdk/src/share/classes/sun/dyn/InvokeGeneric.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.
- */
-
-package sun.dyn;
-
-import java.dyn.*;
-import java.lang.reflect.*;
-import sun.dyn.util.*;
-import static sun.dyn.MethodTypeImpl.invokers;
-
-/**
- * Adapters which manage MethodHanndle.invokeGeneric calls.
- * The JVM calls one of these when the exact type match fails.
- * @author jrose
- */
-class InvokeGeneric {
- // erased type for the call, which originates from an invokeGeneric site
- private final MethodType erasedCallerType;
- // an invoker of type (MT, MH; A...) -> R
- private final MethodHandle initialInvoker;
-
- /** Compute and cache information for this adapter, so that it can
- * call out to targets of the erasure-family of the given erased type.
- */
- private InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException {
- this.erasedCallerType = erasedCallerType;
- this.initialInvoker = makeInitialInvoker();
- assert initialInvoker.type().equals(erasedCallerType
- .insertParameterTypes(0, MethodType.class, MethodHandle.class))
- : initialInvoker.type();
- }
-
- private static MethodHandles.Lookup lookup() {
- return MethodHandleImpl.IMPL_LOOKUP;
- }
-
- /** Return the adapter information for this type's erasure. */
- static MethodHandle genericInvokerOf(MethodType type) {
- MethodTypeImpl form = MethodTypeImpl.of(type);
- MethodHandle genericInvoker = form.genericInvoker;
- if (genericInvoker == null) {
- try {
- InvokeGeneric gen = new InvokeGeneric(form.erasedType());
- form.genericInvoker = genericInvoker = gen.initialInvoker;
- } catch (ReflectiveOperationException ex) {
- throw new RuntimeException(ex);
- }
- }
- return genericInvoker;
- }
-
- private MethodHandle makeInitialInvoker() throws ReflectiveOperationException {
- // postDispatch = #(MH'; MT, MH; A...){MH'(MT, MH; A)}
- MethodHandle postDispatch = makePostDispatchInvoker();
- MethodHandle invoker;
- if (returnConversionPossible()) {
- invoker = MethodHandles.foldArguments(postDispatch,
- dispatcher("dispatchWithConversion"));
- } else {
- invoker = MethodHandles.foldArguments(postDispatch, dispatcher("dispatch"));
- }
- return invoker;
- }
-
- private static final Class>[] EXTRA_ARGS = { MethodType.class, MethodHandle.class };
- private MethodHandle makePostDispatchInvoker() {
- // Take (MH'; MT, MH; A...) and run MH'(MT, MH; A...).
- MethodType invokerType = erasedCallerType.insertParameterTypes(0, EXTRA_ARGS);
- return invokers(invokerType).exactInvoker();
- }
- private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) {
- assert(targetInvoker.type().parameterType(0) == MethodHandle.class);
- return MethodHandles.dropArguments(targetInvoker, 1, EXTRA_ARGS);
- }
-
- private MethodHandle dispatcher(String dispatchName) throws ReflectiveOperationException {
- return lookup().bind(this, dispatchName,
- MethodType.methodType(MethodHandle.class,
- MethodType.class, MethodHandle.class));
- }
-
- static final boolean USE_AS_TYPE_PATH = true;
-
- /** Return a method handle to invoke on the callerType, target, and remaining arguments.
- * The method handle must finish the call.
- * This is the first look at the caller type and target.
- */
- private MethodHandle dispatch(MethodType callerType, MethodHandle target) {
- MethodType targetType = target.type();
- if (USE_AS_TYPE_PATH || target.isVarargsCollector()) {
- MethodHandle newTarget = target.asType(callerType);
- targetType = callerType;
- Invokers invokers = MethodTypeImpl.invokers(Access.TOKEN, targetType);
- MethodHandle invoker = invokers.erasedInvokerWithDrops;
- if (invoker == null) {
- invokers.erasedInvokerWithDrops = invoker =
- dropDispatchArguments(invokers.erasedInvoker());
- }
- return invoker.bindTo(newTarget);
- }
- throw new RuntimeException("NYI");
- }
-
- private MethodHandle dispatchWithConversion(MethodType callerType, MethodHandle target) {
- MethodHandle finisher = dispatch(callerType, target);
- if (returnConversionNeeded(callerType, target))
- finisher = addReturnConversion(finisher, callerType.returnType()); //FIXME: slow
- return finisher;
- }
-
- private boolean returnConversionPossible() {
- Class> needType = erasedCallerType.returnType();
- return !needType.isPrimitive();
- }
- private boolean returnConversionNeeded(MethodType callerType, MethodHandle target) {
- Class> needType = callerType.returnType();
- if (needType == erasedCallerType.returnType())
- return false; // no conversions possible, since must be primitive or Object
- Class> haveType = target.type().returnType();
- if (VerifyType.isNullConversion(haveType, needType))
- return false;
- return true;
- }
- private MethodHandle addReturnConversion(MethodHandle target, Class> type) {
- if (true) throw new RuntimeException("NYI");
- // FIXME: This is slow because it creates a closure node on every call that requires a return cast.
- MethodType targetType = target.type();
- MethodHandle caster = ValueConversions.identity(type);
- caster = caster.asType(MethodType.methodType(type, targetType.returnType()));
- // Drop irrelevant arguments, because we only care about the return value:
- caster = MethodHandles.dropArguments(caster, 1, targetType.parameterList());
- MethodHandle result = MethodHandles.foldArguments(caster, target);
- return result.asType(target.type());
- }
-
- public String toString() {
- return "InvokeGeneric"+erasedCallerType;
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/Invokers.java
--- a/jdk/src/share/classes/sun/dyn/Invokers.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package sun.dyn;
-
-import java.dyn.*;
-import sun.dyn.empty.Empty;
-
-/**
- * Construction and caching of often-used invokers.
- * @author jrose
- */
-public class Invokers {
- // exact type (sans leading taget MH) for the outgoing call
- private final MethodType targetType;
-
- // exact invoker for the outgoing call
- private /*lazy*/ MethodHandle exactInvoker;
-
- // erased (partially untyped but with primitives) invoker for the outgoing call
- private /*lazy*/ MethodHandle erasedInvoker;
- /*lazy*/ MethodHandle erasedInvokerWithDrops; // for InvokeGeneric
-
- // generic (untyped) invoker for the outgoing call
- private /*lazy*/ MethodHandle genericInvoker;
-
- // generic (untyped) invoker for the outgoing call; accepts a single Object[]
- private final /*lazy*/ MethodHandle[] spreadInvokers;
-
- // invoker for an unbound callsite
- private /*lazy*/ MethodHandle uninitializedCallSite;
-
- /** Compute and cache information common to all collecting adapters
- * that implement members of the erasure-family of the given erased type.
- */
- /*non-public*/ Invokers(MethodType targetType) {
- this.targetType = targetType;
- this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1];
- }
-
- public static MethodType invokerType(MethodType targetType) {
- return targetType.insertParameterTypes(0, MethodHandle.class);
- }
-
- public MethodHandle exactInvoker() {
- MethodHandle invoker = exactInvoker;
- if (invoker != null) return invoker;
- try {
- invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invokeExact", targetType);
- } catch (ReflectiveOperationException ex) {
- throw new InternalError("JVM cannot find invoker for "+targetType);
- }
- assert(invokerType(targetType) == invoker.type());
- exactInvoker = invoker;
- return invoker;
- }
-
- public MethodHandle genericInvoker() {
- MethodHandle invoker1 = exactInvoker();
- MethodHandle invoker = genericInvoker;
- if (invoker != null) return invoker;
- MethodType genericType = targetType.generic();
- invoker = MethodHandles.convertArguments(invoker1, invokerType(genericType));
- genericInvoker = invoker;
- return invoker;
- }
-
- public MethodHandle erasedInvoker() {
- MethodHandle invoker1 = exactInvoker();
- MethodHandle invoker = erasedInvoker;
- if (invoker != null) return invoker;
- MethodType erasedType = targetType.erase();
- if (erasedType == targetType.generic())
- invoker = genericInvoker();
- else
- invoker = MethodHandles.convertArguments(invoker1, invokerType(erasedType));
- erasedInvoker = invoker;
- return invoker;
- }
-
- public MethodHandle spreadInvoker(int objectArgCount) {
- MethodHandle vaInvoker = spreadInvokers[objectArgCount];
- if (vaInvoker != null) return vaInvoker;
- MethodHandle gInvoker = genericInvoker();
- vaInvoker = gInvoker.asSpreader(Object[].class, targetType.parameterCount() - objectArgCount);
- spreadInvokers[objectArgCount] = vaInvoker;
- return vaInvoker;
- }
-
- private static MethodHandle THROW_UCS = null;
-
- public MethodHandle uninitializedCallSite() {
- MethodHandle invoker = uninitializedCallSite;
- if (invoker != null) return invoker;
- if (targetType.parameterCount() > 0) {
- MethodType type0 = targetType.dropParameterTypes(0, targetType.parameterCount());
- Invokers invokers0 = MethodTypeImpl.invokers(type0);
- invoker = MethodHandles.dropArguments(invokers0.uninitializedCallSite(),
- 0, targetType.parameterList());
- assert(invoker.type().equals(targetType));
- uninitializedCallSite = invoker;
- return invoker;
- }
- if (THROW_UCS == null) {
- try {
- THROW_UCS = MethodHandleImpl.IMPL_LOOKUP
- .findStatic(CallSite.class, "uninitializedCallSite",
- MethodType.methodType(Empty.class));
- } catch (ReflectiveOperationException ex) {
- throw new RuntimeException(ex);
- }
- }
- invoker = AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, targetType, THROW_UCS);
- assert(invoker.type().equals(targetType));
- uninitializedCallSite = invoker;
- return invoker;
- }
-
- public String toString() {
- return "Invokers"+targetType;
- }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/MemberName.java
--- a/jdk/src/share/classes/sun/dyn/MemberName.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,739 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package sun.dyn;
-
-import sun.dyn.util.BytecodeDescriptor;
-import java.dyn.*;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Member;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import static sun.dyn.MethodHandleNatives.Constants.*;
-
-/**
- * A {@code MemberName} is a compact symbolic datum which fully characterizes
- * a method or field reference.
- * A member name refers to a field, method, constructor, or member type.
- * Every member name has a simple name (a string) and a type (either a Class or MethodType).
- * A member name may also have a non-null declaring class, or it may be simply
- * a naked name/type pair.
- * A member name may also have non-zero modifier flags.
- * Finally, a member name may be either resolved or unresolved.
- * If it is resolved, the existence of the named
- *
- * Whether resolved or not, a member name provides no access rights or
- * invocation capability to its possessor. It is merely a compact
- * representation of all symbolic information necessary to link to
- * and properly use the named member.
- *
- * When resolved, a member name's internal implementation may include references to JVM metadata.
- * This representation is stateless and only decriptive.
- * It provides no private information and no capability to use the member.
- *
- * By contrast, a {@linkplain java.lang.reflect.Method} contains fuller information
- * about the internals of a method (except its bytecodes) and also
- * allows invocation. A MemberName is much lighter than a Method,
- * since it contains about 7 fields to the 16 of Method (plus its sub-arrays),
- * and those seven fields omit much of the information in Method.
- * @author jrose
- */
-public final class MemberName implements Member, Cloneable {
- private Class> clazz; // class in which the method is defined
- private String name; // may be null if not yet materialized
- private Object type; // may be null if not yet materialized
- private int flags; // modifier bits; see reflect.Modifier
-
- private Object vmtarget; // VM-specific target value
- private int vmindex; // method index within class or interface
-
- { vmindex = VM_INDEX_UNINITIALIZED; }
-
- /** Return the declaring class of this member.
- * In the case of a bare name and type, the declaring class will be null.
- */
- public Class> getDeclaringClass() {
- if (clazz == null && isResolved()) {
- expandFromVM();
- }
- return clazz;
- }
-
- /** Utility method producing the class loader of the declaring class. */
- public ClassLoader getClassLoader() {
- return clazz.getClassLoader();
- }
-
- /** Return the simple name of this member.
- * For a type, it is the same as {@link Class#getSimpleName}.
- * For a method or field, it is the simple name of the member.
- * For a constructor, it is always {@code "<init>"}.
- */
- public String getName() {
- if (name == null) {
- expandFromVM();
- if (name == null) return null;
- }
- return name;
- }
-
- /** Return the declared type of this member, which
- * must be a method or constructor.
- */
- public MethodType getMethodType() {
- if (type == null) {
- expandFromVM();
- if (type == null) return null;
- }
- if (!isInvocable())
- throw newIllegalArgumentException("not invocable, no method type");
- if (type instanceof MethodType) {
- return (MethodType) type;
- }
- if (type instanceof String) {
- String sig = (String) type;
- MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
- this.type = res;
- return res;
- }
- if (type instanceof Object[]) {
- Object[] typeInfo = (Object[]) type;
- Class>[] ptypes = (Class>[]) typeInfo[1];
- Class> rtype = (Class>) typeInfo[0];
- MethodType res = MethodType.methodType(rtype, ptypes);
- this.type = res;
- return res;
- }
- throw new InternalError("bad method type "+type);
- }
-
- /** Return the actual type under which this method or constructor must be invoked.
- * For non-static methods or constructors, this is the type with a leading parameter,
- * a reference to declaring class. For static methods, it is the same as the declared type.
- */
- public MethodType getInvocationType() {
- MethodType itype = getMethodType();
- if (!isStatic())
- itype = itype.insertParameterTypes(0, clazz);
- return itype;
- }
-
- /** Utility method producing the parameter types of the method type. */
- public Class>[] getParameterTypes() {
- return getMethodType().parameterArray();
- }
-
- /** Utility method producing the return type of the method type. */
- public Class> getReturnType() {
- return getMethodType().returnType();
- }
-
- /** Return the declared type of this member, which
- * must be a field or type.
- * If it is a type member, that type itself is returned.
- */
- public Class> getFieldType() {
- if (type == null) {
- expandFromVM();
- if (type == null) return null;
- }
- if (isInvocable())
- throw newIllegalArgumentException("not a field or nested class, no simple type");
- if (type instanceof Class>) {
- return (Class>) type;
- }
- if (type instanceof String) {
- String sig = (String) type;
- MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
- Class> res = mtype.returnType();
- this.type = res;
- return res;
- }
- throw new InternalError("bad field type "+type);
- }
-
- /** Utility method to produce either the method type or field type of this member. */
- public Object getType() {
- return (isInvocable() ? getMethodType() : getFieldType());
- }
-
- /** Utility method to produce the signature of this member,
- * used within the class file format to describe its type.
- */
- public String getSignature() {
- if (type == null) {
- expandFromVM();
- if (type == null) return null;
- }
- if (type instanceof String)
- return (String) type;
- if (isInvocable())
- return BytecodeDescriptor.unparse(getMethodType());
- else
- return BytecodeDescriptor.unparse(getFieldType());
- }
-
- /** Return the modifier flags of this member.
- * @see java.lang.reflect.Modifier
- */
- public int getModifiers() {
- return (flags & RECOGNIZED_MODIFIERS);
- }
-
- private void setFlags(int flags) {
- this.flags = flags;
- assert(testAnyFlags(ALL_KINDS));
- }
-
- private boolean testFlags(int mask, int value) {
- return (flags & mask) == value;
- }
- private boolean testAllFlags(int mask) {
- return testFlags(mask, mask);
- }
- private boolean testAnyFlags(int mask) {
- return !testFlags(mask, 0);
- }
-
- /** Utility method to query the modifier flags of this member. */
- public boolean isStatic() {
- return Modifier.isStatic(flags);
- }
- /** Utility method to query the modifier flags of this member. */
- public boolean isPublic() {
- return Modifier.isPublic(flags);
- }
- /** Utility method to query the modifier flags of this member. */
- public boolean isPrivate() {
- return Modifier.isPrivate(flags);
- }
- /** Utility method to query the modifier flags of this member. */
- public boolean isProtected() {
- return Modifier.isProtected(flags);
- }
- /** Utility method to query the modifier flags of this member. */
- public boolean isFinal() {
- return Modifier.isFinal(flags);
- }
- /** Utility method to query the modifier flags of this member. */
- public boolean isAbstract() {
- return Modifier.isAbstract(flags);
- }
- // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
-
- // unofficial modifier flags, used by HotSpot:
- static final int BRIDGE = 0x00000040;
- static final int VARARGS = 0x00000080;
- static final int SYNTHETIC = 0x00001000;
- static final int ANNOTATION= 0x00002000;
- static final int ENUM = 0x00004000;
- /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
- public boolean isBridge() {
- return testAllFlags(IS_METHOD | BRIDGE);
- }
- /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
- public boolean isVarargs() {
- return testAllFlags(VARARGS) && isInvocable();
- }
- /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
- public boolean isSynthetic() {
- return testAllFlags(SYNTHETIC);
- }
-
- static final String CONSTRUCTOR_NAME = ""; // the ever-popular
-
- // modifiers exported by the JVM:
- static final int RECOGNIZED_MODIFIERS = 0xFFFF;
-
- // private flags, not part of RECOGNIZED_MODIFIERS:
- static final int
- IS_METHOD = MN_IS_METHOD, // method (not constructor)
- IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
- IS_FIELD = MN_IS_FIELD, // field
- IS_TYPE = MN_IS_TYPE; // nested type
- static final int // for MethodHandleNatives.getMembers
- SEARCH_SUPERCLASSES = MN_SEARCH_SUPERCLASSES,
- SEARCH_INTERFACES = MN_SEARCH_INTERFACES;
-
- static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
- static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
- static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
- static final int IS_FIELD_OR_METHOD = IS_METHOD | IS_FIELD;
- static final int SEARCH_ALL_SUPERS = SEARCH_SUPERCLASSES | SEARCH_INTERFACES;
-
- /** Utility method to query whether this member is a method or constructor. */
- public boolean isInvocable() {
- return testAnyFlags(IS_INVOCABLE);
- }
- /** Utility method to query whether this member is a method, constructor, or field. */
- public boolean isFieldOrMethod() {
- return testAnyFlags(IS_FIELD_OR_METHOD);
- }
- /** Query whether this member is a method. */
- public boolean isMethod() {
- return testAllFlags(IS_METHOD);
- }
- /** Query whether this member is a constructor. */
- public boolean isConstructor() {
- return testAllFlags(IS_CONSTRUCTOR);
- }
- /** Query whether this member is a field. */
- public boolean isField() {
- return testAllFlags(IS_FIELD);
- }
- /** Query whether this member is a type. */
- public boolean isType() {
- return testAllFlags(IS_TYPE);
- }
- /** Utility method to query whether this member is neither public, private, nor protected. */
- public boolean isPackage() {
- return !testAnyFlags(ALL_ACCESS);
- }
-
- /** Initialize a query. It is not resolved. */
- private void init(Class> defClass, String name, Object type, int flags) {
- // defining class is allowed to be null (for a naked name/type pair)
- //name.toString(); // null check
- //type.equals(type); // null check
- // fill in fields:
- this.clazz = defClass;
- this.name = name;
- this.type = type;
- setFlags(flags);
- assert(!isResolved());
- }
-
- private void expandFromVM() {
- if (!isResolved()) return;
- if (type instanceof Object[])
- type = null; // don't saddle JVM w/ typeInfo
- MethodHandleNatives.expand(this);
- }
-
- // Capturing information from the Core Reflection API:
- private static int flagsMods(int flags, int mods) {
- assert((flags & RECOGNIZED_MODIFIERS) == 0);
- assert((mods & ~RECOGNIZED_MODIFIERS) == 0);
- return flags | mods;
- }
- /** Create a name for the given reflected method. The resulting name will be in a resolved state. */
- public MemberName(Method m) {
- Object[] typeInfo = { m.getReturnType(), m.getParameterTypes() };
- init(m.getDeclaringClass(), m.getName(), typeInfo, flagsMods(IS_METHOD, m.getModifiers()));
- // fill in vmtarget, vmindex while we have m in hand:
- MethodHandleNatives.init(this, m);
- assert(isResolved());
- }
- /** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */
- public MemberName(Constructor ctor) {
- Object[] typeInfo = { void.class, ctor.getParameterTypes() };
- init(ctor.getDeclaringClass(), CONSTRUCTOR_NAME, typeInfo, flagsMods(IS_CONSTRUCTOR, ctor.getModifiers()));
- // fill in vmtarget, vmindex while we have ctor in hand:
- MethodHandleNatives.init(this, ctor);
- assert(isResolved());
- }
- /** Create a name for the given reflected field. The resulting name will be in a resolved state. */
- public MemberName(Field fld) {
- init(fld.getDeclaringClass(), fld.getName(), fld.getType(), flagsMods(IS_FIELD, fld.getModifiers()));
- // fill in vmtarget, vmindex while we have fld in hand:
- MethodHandleNatives.init(this, fld);
- assert(isResolved());
- }
- /** Create a name for the given class. The resulting name will be in a resolved state. */
- public MemberName(Class> type) {
- init(type.getDeclaringClass(), type.getSimpleName(), type, flagsMods(IS_TYPE, type.getModifiers()));
- vmindex = 0; // isResolved
- assert(isResolved());
- }
-
- // bare-bones constructor; the JVM will fill it in
- MemberName() { }
-
- // locally useful cloner
- @Override protected MemberName clone() {
- try {
- return (MemberName) super.clone();
- } catch (CloneNotSupportedException ex) {
- throw new InternalError();
- }
- }
-
- // %%% define equals/hashcode?
-
- // Construction from symbolic parts, for queries:
- /** Create a field or type name from the given components: Declaring class, name, type, modifiers.
- * The declaring class may be supplied as null if this is to be a bare name and type.
- * The resulting name will in an unresolved state.
- */
- public MemberName(Class> defClass, String name, Class> type, int modifiers) {
- init(defClass, name, type, IS_FIELD | (modifiers & RECOGNIZED_MODIFIERS));
- }
- /** Create a field or type name from the given components: Declaring class, name, type.
- * The declaring class may be supplied as null if this is to be a bare name and type.
- * The modifier flags default to zero.
- * The resulting name will in an unresolved state.
- */
- public MemberName(Class> defClass, String name, Class> type) {
- this(defClass, name, type, 0);
- }
- /** Create a method or constructor name from the given components: Declaring class, name, type, modifiers.
- * It will be a constructor if and only if the name is {@code "<init>"}.
- * The declaring class may be supplied as null if this is to be a bare name and type.
- * The resulting name will in an unresolved state.
- */
- public MemberName(Class> defClass, String name, MethodType type, int modifiers) {
- int flagBit = (name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
- init(defClass, name, type, flagBit | (modifiers & RECOGNIZED_MODIFIERS));
- }
- /** Create a method or constructor name from the given components: Declaring class, name, type, modifiers.
- * It will be a constructor if and only if the name is {@code "<init>"}.
- * The declaring class may be supplied as null if this is to be a bare name and type.
- * The modifier flags default to zero.
- * The resulting name will in an unresolved state.
- */
- public MemberName(Class> defClass, String name, MethodType type) {
- this(defClass, name, type, 0);
- }
-
- /** Query whether this member name is resolved.
- * A resolved member name is one for which the JVM has found
- * a method, constructor, field, or type binding corresponding exactly to the name.
- * (Document?)
- */
- public boolean isResolved() {
- return (vmindex != VM_INDEX_UNINITIALIZED);
- }
-
- /** Query whether this member name is resolved to a non-static, non-final method.
- */
- public boolean hasReceiverTypeDispatch() {
- return (isMethod() && getVMIndex(Access.TOKEN) >= 0);
- }
-
- /** Produce a string form of this member name.
- * For types, it is simply the type's own string (as reported by {@code toString}).
- * For fields, it is {@code "DeclaringClass.name/type"}.
- * For methods and constructors, it is {@code "DeclaringClass.name(ptype...)rtype"}.
- * If the declaring class is null, the prefix {@code "DeclaringClass."} is omitted.
- * If the member is unresolved, a prefix {@code "*."} is prepended.
- */
- @Override
- public String toString() {
- if (isType())
- return type.toString(); // class java.lang.String
- // else it is a field, method, or constructor
- StringBuilder buf = new StringBuilder();
- if (getDeclaringClass() != null) {
- buf.append(getName(clazz));
- buf.append('.');
- }
- String name = getName();
- buf.append(name == null ? "*" : name);
- Object type = getType();
- if (!isInvocable()) {
- buf.append('/');
- buf.append(type == null ? "*" : getName(type));
- } else {
- buf.append(type == null ? "(*)*" : getName(type));
- }
- /*
- buf.append('/');
- // key: Public, private, pRotected, sTatic, Final, sYnchronized,
- // transient/Varargs, native, (interface), abstract, sTrict, sYnthetic,
- // (annotation), Enum, (unused)
- final String FIELD_MOD_CHARS = "PprTF?vt????Y?E?";
- final String METHOD_MOD_CHARS = "PprTFybVn?atY???";
- String modChars = (isInvocable() ? METHOD_MOD_CHARS : FIELD_MOD_CHARS);
- for (int i = 0; i < modChars.length(); i++) {
- if ((flags & (1 << i)) != 0) {
- char mc = modChars.charAt(i);
- if (mc != '?')
- buf.append(mc);
- }
- }
- */
- return buf.toString();
- }
- private static String getName(Object obj) {
- if (obj instanceof Class>)
- return ((Class>)obj).getName();
- return String.valueOf(obj);
- }
-
- // Queries to the JVM:
- /** Document? */
- public int getVMIndex(Access token) {
- Access.check(token);
- if (!isResolved())
- throw newIllegalStateException("not resolved");
- return vmindex;
- }
-// public Object getVMTarget(Access token) {
-// Access.check(token);
-// if (!isResolved())
-// throw newIllegalStateException("not resolved");
-// return vmtarget;
-// }
- private RuntimeException newIllegalStateException(String message) {
- return new IllegalStateException(message+": "+this);
- }
-
- // handy shared exception makers (they simplify the common case code)
- public static RuntimeException newIllegalArgumentException(String message) {
- return new IllegalArgumentException(message);
- }
- public static IllegalAccessException newNoAccessException(MemberName name, Object from) {
- return newNoAccessException("cannot access", name, from);
- }
- public static IllegalAccessException newNoAccessException(String message,
- MemberName name, Object from) {
- message += ": " + name;
- if (from != null) message += ", from " + from;
- return new IllegalAccessException(message);
- }
- public static ReflectiveOperationException newNoAccessException(MemberName name) {
- if (name.isResolved())
- return new IllegalAccessException(name.toString());
- else if (name.isConstructor())
- return new NoSuchMethodException(name.toString());
- else if (name.isMethod())
- return new NoSuchMethodException(name.toString());
- else
- return new NoSuchFieldException(name.toString());
- }
- public static Error uncaughtException(Exception ex) {
- Error err = new InternalError("uncaught exception");
- err.initCause(ex);
- return err;
- }
-
- /** Actually making a query requires an access check. */
- public static Factory getFactory(Access token) {
- Access.check(token);
- return Factory.INSTANCE;
- }
- public static Factory getFactory() {
- return getFactory(Access.getToken());
- }
- /** A factory type for resolving member names with the help of the VM.
- * TBD: Define access-safe public constructors for this factory.
- */
- public static class Factory {
- private Factory() { } // singleton pattern
- static Factory INSTANCE = new Factory();
-
- private static int ALLOWED_FLAGS = SEARCH_ALL_SUPERS | ALL_KINDS;
-
- /// Queries
- List getMembers(Class> defc,
- String matchName, Object matchType,
- int matchFlags, Class> lookupClass) {
- matchFlags &= ALLOWED_FLAGS;
- String matchSig = null;
- if (matchType != null) {
- matchSig = BytecodeDescriptor.unparse(matchType);
- if (matchSig.startsWith("("))
- matchFlags &= ~(ALL_KINDS & ~IS_INVOCABLE);
- else
- matchFlags &= ~(ALL_KINDS & ~IS_FIELD);
- }
- final int BUF_MAX = 0x2000;
- int len1 = matchName == null ? 10 : matchType == null ? 4 : 1;
- MemberName[] buf = newMemberBuffer(len1);
- int totalCount = 0;
- ArrayList bufs = null;
- int bufCount = 0;
- for (;;) {
- bufCount = MethodHandleNatives.getMembers(defc,
- matchName, matchSig, matchFlags,
- lookupClass,
- totalCount, buf);
- if (bufCount <= buf.length) {
- if (bufCount < 0) bufCount = 0;
- totalCount += bufCount;
- break;
- }
- // JVM returned to us with an intentional overflow!
- totalCount += buf.length;
- int excess = bufCount - buf.length;
- if (bufs == null) bufs = new ArrayList(1);
- bufs.add(buf);
- int len2 = buf.length;
- len2 = Math.max(len2, excess);
- len2 = Math.max(len2, totalCount / 4);
- buf = newMemberBuffer(Math.min(BUF_MAX, len2));
- }
- ArrayList result = new ArrayList(totalCount);
- if (bufs != null) {
- for (MemberName[] buf0 : bufs) {
- Collections.addAll(result, buf0);
- }
- }
- result.addAll(Arrays.asList(buf).subList(0, bufCount));
- // Signature matching is not the same as type matching, since
- // one signature might correspond to several types.
- // So if matchType is a Class or MethodType, refilter the results.
- if (matchType != null && matchType != matchSig) {
- for (Iterator it = result.iterator(); it.hasNext();) {
- MemberName m = it.next();
- if (!matchType.equals(m.getType()))
- it.remove();
- }
- }
- return result;
- }
- boolean resolveInPlace(MemberName m, boolean searchSupers, Class> lookupClass) {
- if (m.name == null || m.type == null) { // find unique non-overloaded name
- Class> defc = m.getDeclaringClass();
- List choices = null;
- if (m.isMethod())
- choices = getMethods(defc, searchSupers, m.name, (MethodType) m.type, lookupClass);
- else if (m.isConstructor())
- choices = getConstructors(defc, lookupClass);
- else if (m.isField())
- choices = getFields(defc, searchSupers, m.name, (Class>) m.type, lookupClass);
- //System.out.println("resolving "+m+" to "+choices);
- if (choices == null || choices.size() != 1)
- return false;
- if (m.name == null) m.name = choices.get(0).name;
- if (m.type == null) m.type = choices.get(0).type;
- }
- MethodHandleNatives.resolve(m, lookupClass);
- if (m.isResolved()) return true;
- int matchFlags = m.flags | (searchSupers ? SEARCH_ALL_SUPERS : 0);
- String matchSig = m.getSignature();
- MemberName[] buf = { m };
- int n = MethodHandleNatives.getMembers(m.getDeclaringClass(),
- m.getName(), matchSig, matchFlags, lookupClass, 0, buf);
- if (n != 1) return false;
- return m.isResolved();
- }
- /** Produce a resolved version of the given member.
- * Super types are searched (for inherited members) if {@code searchSupers} is true.
- * Access checking is performed on behalf of the given {@code lookupClass}.
- * If lookup fails or access is not permitted, null is returned.
- * Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
- */
- public MemberName resolveOrNull(MemberName m, boolean searchSupers, Class> lookupClass) {
- MemberName result = m.clone();
- if (resolveInPlace(result, searchSupers, lookupClass))
- return result;
- return null;
- }
- /** Produce a resolved version of the given member.
- * Super types are searched (for inherited members) if {@code searchSupers} is true.
- * Access checking is performed on behalf of the given {@code lookupClass}.
- * If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown.
- * Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
- */
- public
-
- MemberName resolveOrFail(MemberName m, boolean searchSupers, Class> lookupClass,
- Class nsmClass)
- throws IllegalAccessException, NoSuchMemberException {
- MemberName result = resolveOrNull(m, searchSupers, lookupClass);
- if (result != null)
- return result;
- ReflectiveOperationException ex = newNoAccessException(m);
- if (ex instanceof IllegalAccessException) throw (IllegalAccessException) ex;
- throw nsmClass.cast(ex);
- }
- /** Return a list of all methods defined by the given class.
- * Super types are searched (for inherited members) if {@code searchSupers} is true.
- * Access checking is performed on behalf of the given {@code lookupClass}.
- * Inaccessible members are not added to the last.
- */
- public List getMethods(Class> defc, boolean searchSupers,
- Class> lookupClass) {
- return getMethods(defc, searchSupers, null, null, lookupClass);
- }
- /** Return a list of matching methods defined by the given class.
- * Super types are searched (for inherited members) if {@code searchSupers} is true.
- * Returned methods will match the name (if not null) and the type (if not null).
- * Access checking is performed on behalf of the given {@code lookupClass}.
- * Inaccessible members are not added to the last.
- */
- public List getMethods(Class> defc, boolean searchSupers,
- String name, MethodType type, Class> lookupClass) {
- int matchFlags = IS_METHOD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
- return getMembers(defc, name, type, matchFlags, lookupClass);
- }
- /** Return a list of all constructors defined by the given class.
- * Access checking is performed on behalf of the given {@code lookupClass}.
- * Inaccessible members are not added to the last.
- */
- public List getConstructors(Class> defc, Class> lookupClass) {
- return getMembers(defc, null, null, IS_CONSTRUCTOR, lookupClass);
- }
- /** Return a list of all fields defined by the given class.
- * Super types are searched (for inherited members) if {@code searchSupers} is true.
- * Access checking is performed on behalf of the given {@code lookupClass}.
- * Inaccessible members are not added to the last.
- */
- public List getFields(Class> defc, boolean searchSupers,
- Class> lookupClass) {
- return getFields(defc, searchSupers, null, null, lookupClass);
- }
- /** Return a list of all fields defined by the given class.
- * Super types are searched (for inherited members) if {@code searchSupers} is true.
- * Returned fields will match the name (if not null) and the type (if not null).
- * Access checking is performed on behalf of the given {@code lookupClass}.
- * Inaccessible members are not added to the last.
- */
- public List getFields(Class> defc, boolean searchSupers,
- String name, Class> type, Class> lookupClass) {
- int matchFlags = IS_FIELD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
- return getMembers(defc, name, type, matchFlags, lookupClass);
- }
- /** Return a list of all nested types defined by the given class.
- * Super types are searched (for inherited members) if {@code searchSupers} is true.
- * Access checking is performed on behalf of the given {@code lookupClass}.
- * Inaccessible members are not added to the last.
- */
- public List getNestedTypes(Class> defc, boolean searchSupers,
- Class> lookupClass) {
- int matchFlags = IS_TYPE | (searchSupers ? SEARCH_ALL_SUPERS : 0);
- return getMembers(defc, null, null, matchFlags, lookupClass);
- }
- private static MemberName[] newMemberBuffer(int length) {
- MemberName[] buf = new MemberName[length];
- // fill the buffer with dummy structs for the JVM to fill in
- for (int i = 0; i < length; i++)
- buf[i] = new MemberName();
- return buf;
- }
- }
-
-// static {
-// System.out.println("Hello world! My methods are:");
-// System.out.println(Factory.INSTANCE.getMethods(MemberName.class, true, null));
-// }
-}
diff -r 6aa795396cc8 -r 376ac0a67571 jdk/src/share/classes/sun/dyn/MethodHandleImpl.java
--- a/jdk/src/share/classes/sun/dyn/MethodHandleImpl.java Sat Mar 26 00:11:34 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1284 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, 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.
- */
-
-package sun.dyn;
-
-import java.dyn.*;
-import java.dyn.MethodHandles.Lookup;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import sun.dyn.util.VerifyType;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import sun.dyn.empty.Empty;
-import sun.dyn.util.ValueConversions;
-import sun.dyn.util.Wrapper;
-import sun.misc.Unsafe;
-import static sun.dyn.MemberName.newIllegalArgumentException;
-import static sun.dyn.MemberName.newNoAccessException;
-import static sun.dyn.MemberName.uncaughtException;
-
-/**
- * Base class for method handles, containing JVM-specific fields and logic.
- * TO DO: It should not be a base class.
- * @author jrose
- */
-public abstract class MethodHandleImpl {
-
- // Fields which really belong in MethodHandle:
- private byte vmentry; // adapter stub or method entry point
- //private int vmslots; // optionally, hoist type.form.vmslots
- protected Object vmtarget; // VM-specific, class-specific target value
- //MethodType type; // defined in MethodHandle
-
- // TO DO: vmtarget should be invisible to Java, since the JVM puts internal
- // managed pointers into it. Making it visible exposes it to debuggers,
- // which can cause errors when they treat the pointer as an Object.
-
- // These two dummy fields are present to force 'I' and 'J' signatures
- // into this class's constant pool, so they can be transferred
- // to vmentry when this class is loaded.
- static final int INT_FIELD = 0;
- static final long LONG_FIELD = 0;
-
- /** Access methods for the internals of MethodHandle, supplied to
- * MethodHandleImpl as a trusted agent.
- */
- static public interface MethodHandleFriend {
- void initType(MethodHandle mh, MethodType type);
- }
- public static void setMethodHandleFriend(Access token, MethodHandleFriend am) {
- Access.check(token);
- if (METHOD_HANDLE_FRIEND != null)
- throw new InternalError(); // just once
- METHOD_HANDLE_FRIEND = am;
- }
- static private MethodHandleFriend METHOD_HANDLE_FRIEND;
-
- // NOT public
- static void initType(MethodHandle mh, MethodType type) {
- METHOD_HANDLE_FRIEND.initType(mh, type);
- }
-
- // type is defined in java.dyn.MethodHandle, which is platform-independent
-
- // vmentry (a void* field) is used *only* by by the JVM.
- // The JVM adjusts its type to int or long depending on system wordsize.
- // Since it is statically typed as neither int nor long, it is impossible
- // to use this field from Java bytecode. (Please don't try to, either.)
-
- // The vmentry is an assembly-language stub which is jumped to
- // immediately after the method type is verified.
- // For a direct MH, this stub loads the vmtarget's entry point
- // and jumps to it.
-
- /**
- * VM-based method handles must have a security token.
- * This security token can only be obtained by trusted code.
- * Do not create method handles directly; use factory methods.
- */
- public MethodHandleImpl(Access token) {
- Access.check(token);
- }
-
- /** Initialize the method type form to participate in JVM calls.
- * This is done once for each erased type.
- */
- public static void init(Access token, MethodType self) {
- Access.check(token);
- if (MethodHandleNatives.JVM_SUPPORT)
- MethodHandleNatives.init(self);
- }
-
- /// Factory methods to create method handles:
-
- private static final MemberName.Factory LOOKUP = MemberName.Factory.INSTANCE;
-
- static private Lookup IMPL_LOOKUP_INIT;
-
- public static void initLookup(Access token, Lookup lookup) {
- Access.check(token);
- if (IMPL_LOOKUP_INIT != null)
- throw new InternalError();
- IMPL_LOOKUP_INIT = lookup;
- }
-
- public static Lookup getLookup(Access token) {
- Access.check(token);
- return IMPL_LOOKUP;
- }
-
- static {
- if (!MethodHandleNatives.JVM_SUPPORT) // force init of native API
- throw new InternalError("No JVM support for JSR 292");
- // Force initialization of Lookup, so it calls us back as initLookup:
- MethodHandles.publicLookup();
- if (IMPL_LOOKUP_INIT == null)
- throw new InternalError();
- }
-
- public static void initStatics() {
- // Trigger preceding sequence.
- }
-
- /** Shared secret with MethodHandles.Lookup, a copy of Lookup.IMPL_LOOKUP. */
- static final Lookup IMPL_LOOKUP = IMPL_LOOKUP_INIT;
-
-
- /** Look up a given method.
- * Callable only from java.dyn and related packages.
- *
- * The resulting method handle type will be of the given type,
- * with a receiver type {@code rcvc} prepended if the member is not static.
- *
- * Access checks are made as of the given lookup class.
- * In particular, if the method is protected and {@code defc} is in a
- * different package from the lookup class, then {@code rcvc} must be
- * the lookup class or a subclass.
- * @param token Proof that the lookup class has access to this package.
- * @param member Resolved method or constructor to call.
- * @param name Name of the desired method.
- * @param rcvc Receiver type of desired non-static method (else null)
- * @param doDispatch whether the method handle will test the receiver type
- * @param lookupClass access-check relative to this class
- * @return a direct handle to the matching method
- * @throws IllegalAccessException if the given method cannot be accessed by the lookup class
- */
- public static
- MethodHandle findMethod(Access token, MemberName method,
- boolean doDispatch, Class> lookupClass) throws IllegalAccessException {
- Access.check(token); // only trusted calls
- MethodType mtype = method.getMethodType();
- if (!method.isStatic()) {
- // adjust the advertised receiver type to be exactly the one requested
- // (in the case of invokespecial, this will be the calling class)
- Class> recvType = method.getDeclaringClass();
- mtype = mtype.insertParameterTypes(0, recvType);
- }
- DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass);
- if (!mh.isValid())
- throw newNoAccessException(method, lookupClass);
- assert(mh.type() == mtype);
- if (!method.isVarargs())
- return mh;
- else
- return mh.asVarargsCollector(mtype.parameterType(mtype.parameterCount()-1));
- }
-
- public static
- MethodHandle makeAllocator(Access token, MethodHandle rawConstructor) {
- Access.check(token);
- MethodType rawConType = rawConstructor.type();
- // Wrap the raw (unsafe) constructor with the allocation of a suitable object.
- MethodHandle allocator
- = AllocateObject.make(token, rawConType.parameterType(0), rawConstructor);
- assert(allocator.type()
- .equals(rawConType.dropParameterTypes(0, 1).changeReturnType(rawConType.parameterType(0))));
- return allocator;
- }
-
- static final class AllocateObject extends BoundMethodHandle {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
-
- private final Class allocateClass;
- private final MethodHandle rawConstructor;
-
- private AllocateObject(MethodHandle invoker,
- Class allocateClass, MethodHandle rawConstructor) {
- super(Access.TOKEN, invoker);
- this.allocateClass = allocateClass;
- this.rawConstructor = rawConstructor;
- }
- static MethodHandle make(Access token,
- Class> allocateClass, MethodHandle rawConstructor) {
- Access.check(token);
- MethodType rawConType = rawConstructor.type();
- assert(rawConType.parameterType(0) == allocateClass);
- MethodType newType = rawConType.dropParameterTypes(0, 1).changeReturnType(allocateClass);
- int nargs = rawConType.parameterCount() - 1;
- if (nargs < INVOKES.length) {
- MethodHandle invoke = INVOKES[nargs];
- MethodType conType = CON_TYPES[nargs];
- MethodHandle gcon = convertArguments(token, rawConstructor, conType, rawConType, null);
- if (gcon == null) return null;
- MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
- assert(galloc.type() == newType.generic());
- return convertArguments(token, galloc, newType, galloc.type(), null);
- } else {
- MethodHandle invoke = VARARGS_INVOKE;
- MethodType conType = CON_TYPES[nargs];
- MethodHandle gcon = spreadArguments(token, rawConstructor, conType, 1);
- if (gcon == null) return null;
- MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
- return collectArguments(token, galloc, newType, 1, null);
- }
- }
- @Override
- public String toString() {
- return addTypeString(allocateClass.getSimpleName(), this);
- }
- @SuppressWarnings("unchecked")
- private C allocate() throws InstantiationException {
- return (C) unsafe.allocateInstance(allocateClass);
- }
- private C invoke_V(Object... av) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, av);
- return obj;
- }
- private C invoke_L0() throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj);
- return obj;
- }
- private C invoke_L1(Object a0) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, a0);
- return obj;
- }
- private C invoke_L2(Object a0, Object a1) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, a0, a1);
- return obj;
- }
- private C invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, a0, a1, a2);
- return obj;
- }
- private C invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3);
- return obj;
- }
- private C invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4);
- return obj;
- }
- private C invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5);
- return obj;
- }
- private C invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5, a6);
- return obj;
- }
- private C invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
- C obj = allocate();
- rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5, a6, a7);
- return obj;
- }
- static MethodHandle[] makeInvokes() {
- ArrayList invokes = new ArrayList();
- MethodHandles.Lookup lookup = IMPL_LOOKUP;
- for (;;) {
- int nargs = invokes.size();
- String name = "invoke_L"+nargs;
- MethodHandle invoke = null;
- try {
- invoke = lookup.findVirtual(AllocateObject.class, name, MethodType.genericMethodType(nargs));
- } catch (ReflectiveOperationException ex) {
- }
- if (invoke == null) break;
- invokes.add(invoke);
- }
- assert(invokes.size() == 9); // current number of methods
- return invokes.toArray(new MethodHandle[0]);
- };
- static final MethodHandle[] INVOKES = makeInvokes();
- // For testing use this:
- //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
- static final MethodHandle VARARGS_INVOKE;
- static {
- try {
- VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "invoke_V", MethodType.genericMethodType(0, true));
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- }
- // Corresponding generic constructor types:
- static final MethodType[] CON_TYPES = new MethodType[INVOKES.length];
- static {
- for (int i = 0; i < INVOKES.length; i++)
- CON_TYPES[i] = makeConType(INVOKES[i]);
- }
- static final MethodType VARARGS_CON_TYPE = makeConType(VARARGS_INVOKE);
- static MethodType makeConType(MethodHandle invoke) {
- MethodType invType = invoke.type();
- return invType.changeParameterType(0, Object.class).changeReturnType(void.class);
- }
- }
-
- public static
- MethodHandle accessField(Access token,
- MemberName member, boolean isSetter,
- Class> lookupClass) {
- Access.check(token);
- // Use sun. misc.Unsafe to dig up the dirt on the field.
- MethodHandle mh = new FieldAccessor(token, member, isSetter);
- return mh;
- }
-
- public static
- MethodHandle accessArrayElement(Access token,
- Class> arrayClass, boolean isSetter) {
- Access.check(token);
- if (!arrayClass.isArray())
- throw newIllegalArgumentException("not an array: "+arrayClass);
- Class> elemClass = arrayClass.getComponentType();
- MethodHandle[] mhs = FieldAccessor.ARRAY_CACHE.get(elemClass);
- if (mhs == null) {
- if (!FieldAccessor.doCache(elemClass))
- return FieldAccessor.ahandle(arrayClass, isSetter);
- mhs = new MethodHandle[] {
- FieldAccessor.ahandle(arrayClass, false),
- FieldAccessor.ahandle(arrayClass, true)
- };
- if (mhs[0].type().parameterType(0) == Class.class) {
- mhs[0] = MethodHandles.insertArguments(mhs[0], 0, elemClass);
- mhs[1] = MethodHandles.insertArguments(mhs[1], 0, elemClass);
- }
- synchronized (FieldAccessor.ARRAY_CACHE) {} // memory barrier
- FieldAccessor.ARRAY_CACHE.put(elemClass, mhs);
- }
- return mhs[isSetter ? 1 : 0];
- }
-
- static final class FieldAccessor extends BoundMethodHandle {
- private static final Unsafe unsafe = Unsafe.getUnsafe();
- final Object base; // for static refs only
- final long offset;
- final String name;
-
- public FieldAccessor(Access token, MemberName field, boolean isSetter) {
- super(Access.TOKEN, fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic()));
- this.offset = (long) field.getVMIndex(token);
- this.name = field.getName();
- this.base = staticBase(field);
- }
- public String toString() { return addTypeString(name, this); }
-
- int getFieldI(C obj) { return unsafe.getInt(obj, offset); }
- void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); }
- long getFieldJ(C obj) { return unsafe.getLong(obj, offset); }
- void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); }
- float getFieldF(C obj) { return unsafe.getFloat(obj, offset); }
- void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); }
- double getFieldD(C obj) { return unsafe.getDouble(obj, offset); }
- void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); }
- boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); }
- void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
- byte getFieldB(C obj) { return unsafe.getByte(obj, offset); }
- void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); }
- short getFieldS(C obj) { return unsafe.getShort(obj, offset); }
- void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); }
- char getFieldC(C obj) { return unsafe.getChar(obj, offset); }
- void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); }
- @SuppressWarnings("unchecked")
- V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); }
- @SuppressWarnings("unchecked")
- void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); }
- // cast (V) is OK here, since we wrap convertArguments around the MH.
-
- static Object staticBase(MemberName field) {
- if (!field.isStatic()) return null;
- Class c = field.getDeclaringClass();
- java.lang.reflect.Field f;
- try {
- // FIXME: Should not have to create 'f' to get this value.
- f = c.getDeclaredField(field.getName());
- return unsafe.staticFieldBase(f);
- } catch (Exception ee) {
- throw uncaughtException(ee);
- }
- }
-
- int getStaticI() { return unsafe.getInt(base, offset); }
- void setStaticI(int x) { unsafe.putInt(base, offset, x); }
- long getStaticJ() { return unsafe.getLong(base, offset); }
- void setStaticJ(long x) { unsafe.putLong(base, offset, x); }
- float getStaticF() { return unsafe.getFloat(base, offset); }
- void setStaticF(float x) { unsafe.putFloat(base, offset, x); }
- double getStaticD() { return unsafe.getDouble(base, offset); }
- void setStaticD(double x) { unsafe.putDouble(base, offset, x); }
- boolean getStaticZ() { return unsafe.getBoolean(base, offset); }
- void setStaticZ(boolean x) { unsafe.putBoolean(base, offset, x); }
- byte getStaticB() { return unsafe.getByte(base, offset); }
- void setStaticB(byte x) { unsafe.putByte(base, offset, x); }
- short getStaticS() { return unsafe.getShort(base, offset); }
- void setStaticS(short x) { unsafe.putShort(base, offset, x); }
- char getStaticC() { return unsafe.getChar(base, offset); }
- void setStaticC(char x) { unsafe.putChar(base, offset, x); }
- V getStaticL() { return (V) unsafe.getObject(base, offset); }
- void setStaticL(V x) { unsafe.putObject(base, offset, x); }
-
- static String fname(Class> vclass, boolean isSetter, boolean isStatic) {
- String stem;
- if (!isStatic)
- stem = (!isSetter ? "getField" : "setField");
- else
- stem = (!isSetter ? "getStatic" : "setStatic");
- return stem + Wrapper.basicTypeChar(vclass);
- }
- static MethodType ftype(Class> cclass, Class> vclass, boolean isSetter, boolean isStatic) {
- MethodType type;
- if (!isStatic) {
- if (!isSetter)
- return MethodType.methodType(vclass, cclass);
- else
- return MethodType.methodType(void.class, cclass, vclass);
- } else {
- if (!isSetter)
- return MethodType.methodType(vclass);
- else
- return MethodType.methodType(void.class, vclass);
- }
- }
- static MethodHandle fhandle(Class> cclass, Class> vclass, boolean isSetter, boolean isStatic) {
- String name = FieldAccessor.fname(vclass, isSetter, isStatic);
- if (cclass.isPrimitive()) throw newIllegalArgumentException("primitive "+cclass);
- Class> ecclass = Object.class; //erase this type
- Class> evclass = vclass;
- if (!evclass.isPrimitive()) evclass = Object.class;
- MethodType type = FieldAccessor.ftype(ecclass, evclass, isSetter, isStatic);
- MethodHandle mh;
- try {
- mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- if (evclass != vclass || (!isStatic && ecclass != cclass)) {
- MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic);
- strongType = strongType.insertParameterTypes(0, FieldAccessor.class);
- mh = MethodHandles.convertArguments(mh, strongType);
- }
- return mh;
- }
-
- /// Support for array element access
- static final HashMap, MethodHandle[]> ARRAY_CACHE =
- new HashMap, MethodHandle[]>();
- // FIXME: Cache on the classes themselves, not here.
- static boolean doCache(Class> elemClass) {
- if (elemClass.isPrimitive()) return true;
- ClassLoader cl = elemClass.getClassLoader();
- return cl == null || cl == ClassLoader.getSystemClassLoader();
- }
- static int getElementI(int[] a, int i) { return a[i]; }
- static void setElementI(int[] a, int i, int x) { a[i] = x; }
- static long getElementJ(long[] a, int i) { return a[i]; }
- static void setElementJ(long[] a, int i, long x) { a[i] = x; }
- static float getElementF(float[] a, int i) { return a[i]; }
- static void setElementF(float[] a, int i, float x) { a[i] = x; }
- static double getElementD(double[] a, int i) { return a[i]; }
- static void setElementD(double[] a, int i, double x) { a[i] = x; }
- static boolean getElementZ(boolean[] a, int i) { return a[i]; }
- static void setElementZ(boolean[] a, int i, boolean x) { a[i] = x; }
- static byte getElementB(byte[] a, int i) { return a[i]; }
- static void setElementB(byte[] a, int i, byte x) { a[i] = x; }
- static short getElementS(short[] a, int i) { return a[i]; }
- static void setElementS(short[] a, int i, short x) { a[i] = x; }
- static char getElementC(char[] a, int i) { return a[i]; }
- static void setElementC(char[] a, int i, char x) { a[i] = x; }
- static Object getElementL(Object[] a, int i) { return a[i]; }
- static void setElementL(Object[] a, int i, Object x) { a[i] = x; }
- static V getElementL(Class aclass, V[] a, int i) { return aclass.cast(a)[i]; }
- static void setElementL(Class aclass, V[] a, int i, V x) { aclass.cast(a)[i] = x; }
-
- static String aname(Class> aclass, boolean isSetter) {
- Class> vclass = aclass.getComponentType();
- if (vclass == null) throw new IllegalArgumentException();
- return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(vclass);
- }
- static MethodType atype(Class> aclass, boolean isSetter) {
- Class> vclass = aclass.getComponentType();
- if (!isSetter)
- return MethodType.methodType(vclass, aclass, int.class);
- else
- return MethodType.methodType(void.class, aclass, int.class, vclass);
- }
- static MethodHandle ahandle(Class> aclass, boolean isSetter) {
- Class> vclass = aclass.getComponentType();
- String name = FieldAccessor.aname(aclass, isSetter);
- Class> caclass = null;
- if (!vclass.isPrimitive() && vclass != Object.class) {
- caclass = aclass;
- aclass = Object[].class;
- vclass = Object.class;
- }
- MethodType type = FieldAccessor.atype(aclass, isSetter);
- if (caclass != null)
- type = type.insertParameterTypes(0, Class.class);
- MethodHandle mh;
- try {
- mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
- } catch (ReflectiveOperationException ex) {
- throw uncaughtException(ex);
- }
- if (caclass != null) {
- MethodType strongType = FieldAccessor.atype(caclass, isSetter);
- mh = MethodHandles.insertArguments(mh, 0, caclass);
- mh = MethodHandles.convertArguments(mh, strongType);
- }
- return mh;
- }
- }
-
- /** Bind a predetermined first argument to the given direct method handle.
- * Callable only from MethodHandles.
- * @param token Proof that the caller has access to this package.
- * @param target Any direct method handle.
- * @param receiver Receiver (or first static method argument) to pre-bind.
- * @return a BoundMethodHandle for the given DirectMethodHandle, or null if it does not exist
- */
- public static
- MethodHandle bindReceiver(Access token,
- MethodHandle target, Object receiver) {
- Access.check(token);
- if (target instanceof AdapterMethodHandle &&
- ((AdapterMethodHandle)target).conversionOp() == MethodHandleNatives.Constants.OP_RETYPE_ONLY
- ) {
- Object info = MethodHandleNatives.getTargetInfo(target);
- if (info instanceof DirectMethodHandle) {
- DirectMethodHandle dmh = (DirectMethodHandle) info;
- if (receiver == null ||
- dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) {
- MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0);
- MethodType newType = target.type().dropParameterTypes(0, 1);
- return convertArguments(token, bmh, newType, bmh.type(), null);
- }
- }
- }
- if (target instanceof DirectMethodHandle)
- return new BoundMethodHandle((DirectMethodHandle)target, receiver, 0);
- return null; // let caller try something else
- }
-
- /** Bind a predetermined argument to the given arbitrary method handle.
- * Callable only from MethodHandles.
- * @param token Proof that the caller has access to this package.
- * @param target Any method handle.
- * @param receiver Argument (which can be a boxed primitive) to pre-bind.
- * @return a suitable BoundMethodHandle
- */
- public static
- MethodHandle bindArgument(Access token,
- MethodHandle target, int argnum, Object receiver) {
- Access.check(token);
- return new BoundMethodHandle(target, receiver, argnum);
- }
-
- public static MethodHandle convertArguments(Access token,
- MethodHandle target,
- MethodType newType,
- MethodType oldType,
- int[] permutationOrNull) {
- Access.check(token);
- assert(oldType.parameterCount() == target.type().parameterCount());
- if (permutationOrNull != null) {
- int outargs = oldType.parameterCount(), inargs = newType.parameterCount();
- if (permutationOrNull.length != outargs)
- throw newIllegalArgumentException("wrong number of arguments in permutation");
- // Make the individual outgoing argument types match up first.
- Class>[] callTypeArgs = new Class>[outargs];
- for (int i = 0; i < outargs; i++)
- callTypeArgs[i] = newType.parameterType(permutationOrNull[i]);
- MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs);
- target = convertArguments(token, target, callType, oldType, null);
- assert(target != null);
- oldType = target.type();
- List goal = new ArrayList(); // i*TOKEN
- List state = new ArrayList(); // i*TOKEN
- List drops = new ArrayList(); // not tokens
- List