提交 4eb43f64 编写于 作者: J jrose

6914665: update jdk code for JSR 292 (post 6858164)

Summary: Fill in missing API implementations, fix numerous bugs, adjust APIs towards EG design.
Reviewed-by: twisti
上级 6145be84
......@@ -26,6 +26,9 @@
package java.dyn;
import sun.dyn.util.BytecodeName;
import sun.dyn.Access;
import sun.dyn.CallSiteImpl;
import sun.dyn.MethodHandleImpl;
/**
* An {@code invokedynamic} call site, as reified by the
......@@ -52,15 +55,25 @@ import sun.dyn.util.BytecodeName;
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
* @author John Rose, JSR 292 EG
*/
public class CallSite {
public class CallSite
// 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 CallSiteImpl
{
private static final Access IMPL_TOKEN = Access.getToken();
/*
// Fields used only by the JVM. Do not use or change.
private Object vmmethod;
int callerMID, callerBCI; // supplied by the JVM
MethodHandle target;
private MethodHandle target;
final Object caller; // usually a class
final String name;
final MethodType type;
*/
/**
* Make a call site given the parameters from a call to the bootstrap method.
......@@ -72,16 +85,21 @@ public class CallSite {
* @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
*/
public CallSite(Object caller, String name, MethodType type) {
this.caller = caller;
this.name = name;
this.type = type;
super(IMPL_TOKEN, caller, name, type);
}
private static void privateInitializeCallSite(CallSite site, int callerMID, int callerBCI) {
site.callerMID = callerMID;
site.callerBCI = callerBCI;
if (site.target == null)
site.setTarget(site.initialTarget());
site.ensureTarget();
}
private void ensureTarget() {
// Note use of super, which accesses the field directly,
// without deferring to possible subclass overrides.
if (super.getTarget() == null) {
super.setTarget(this.initialTarget());
super.getTarget().type(); // provoke NPE if still null
}
}
/**
......@@ -102,10 +120,11 @@ public class CallSite {
/**
* Report the current linkage state of the call site. (This is mutable.)
* The value maybe null only if the call site is currently unlinked.
* When a linked call site is invoked, the target method is used directly.
* When an unlinked call site is invoked, its bootstrap method receives
* the call, as if via {@link Linkage#bootstrapInvokeDynamic}.
* The value may not be null after the {@code CallSite} object is returned
* from the bootstrap method of the {@code invokedynamic} instruction.
* When an {@code invokedynamic} instruction is executed, the target method
* of its associated {@code call site} object is invoked directly,
* as if via {@link MethodHandle}{@code .invoke}.
* <p>
* 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
......@@ -118,7 +137,7 @@ public class CallSite {
* @see #setTarget
*/
public MethodHandle getTarget() {
return target;
return super.getTarget();
}
/**
......@@ -140,13 +159,13 @@ public class CallSite {
*/
public void setTarget(MethodHandle target) {
checkTarget(target);
this.target = target;
super.setTarget(target);
}
protected void checkTarget(MethodHandle target) {
target.type(); // provoke NPE
if (!canSetTarget(target))
throw new WrongMethodTypeException(String.valueOf(target));
throw new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type());
}
protected boolean canSetTarget(MethodHandle target) {
......@@ -219,6 +238,10 @@ public class CallSite {
@Override
public String toString() {
return "CallSite#"+hashCode()+"["+name+type+" => "+target+"]";
return "CallSite#"+hashCode()+"["+name+type+" => "+getTarget()+"]";
}
// Package-local constant:
static final MethodHandle GET_TARGET = MethodHandleImpl.getLookup(IMPL_TOKEN).
findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
}
......@@ -45,6 +45,24 @@ package java.dyn;
* class or interface supertype, or an object type; it can never be instantiated.
* Logically, it denotes a source of all dynamically typed methods.
* It may be viewed as a pure syntactic marker (an importable one) of static calls.
* <p>
* Here are some examples of usage:
* <p><blockquote><pre>
* Object x; String s; int i;
* x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
* s = InvokeDynamic.&lt;String&gt;hail(x); // hail(Ljava/lang/Object;)Ljava/lang/String;
* InvokeDynamic.&lt;void&gt;cogito(); // cogito()V
* i = InvokeDynamic.&lt;int&gt;#"op:+"(2, 3); // "op:+"(II)I
* </pre></blockquote>
* Each of the above calls generates a single invokedynamic instruction
* with the name-and-type descriptors indicated in the comments.
* The argument types are taken directly from the actual arguments,
* while the return type is taken from the type parameter.
* (This type parameter may be a primtive, and it defaults to {@code Object}.)
* The final example uses a special syntax for uttering non-Java names.
* Any name legal to the JVM may be given between the double quotes.
* None of these calls is complete without a bootstrap method,
* which must be registered by the static initializer of the enclosing class.
* @author John Rose, JSR 292 EG
*/
public final class InvokeDynamic {
......
......@@ -52,4 +52,16 @@ public class InvokeDynamicBootstrapError extends LinkageError {
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.
*/
public InvokeDynamicBootstrapError(String s, Throwable cause) {
super(s);
this.initCause(cause);
}
}
......@@ -25,6 +25,8 @@
package java.dyn;
import sun.dyn.Access;
/**
* A Java method handle extends the basic method handle type with additional
* programmer defined methods and fields.
......@@ -39,31 +41,105 @@ package java.dyn;
* of the entry point method handle, with the leading parameter type
* omitted.
* <p>
* Here is an example of usage:
* Here is an example of usage, creating a hybrid object/functional datum:
* <p><blockquote><pre>
* class Greeter extends JavaMethodHandle {
* private String greeting = "hello";
* public void setGreeting(String s) { greeting = s; }
* public void run() { System.out.println(greeting+", "+greetee); }
* private final String greetee;
* Greeter(String greetee) {
* super(RUN); // alternatively, super("run")
* this.greetee = greetee;
* }
* // the entry point function is computed once:
* private static final MethodHandle RUN
* = MethodHandles.lookup().findVirtual(Greeter.class, "run",
* MethodType.make(void.class));
* }
* // class Main { public static void main(String... av) { ...
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
* // Statically typed method handle invocation (most direct):
* MethodHandle mh = greeter;
* mh.&lt;void&gt;invoke(); // also prints "hello, world"
* // Dynamically typed method handle invocation:
* MethodHandles.invoke(greeter); // also prints "hello, world"
* greeter.setGreeting("howdy");
* mh.invoke(); // prints "howdy, world" (object-like mutable behavior)
* </pre></blockquote>
* <p>
* In the example of {@code Greeter}, the method {@code run} provides the entry point.
* The entry point need not be a constant value; it may be independently
* computed in each call to the constructor. The entry point does not
* even need to be a method on the {@code Greeter} class, though
* that is the typical case.
* <p>
* The entry point may also be provided symbolically, in which case the the
* {@code JavaMethodHandle} constructor performs the lookup of the entry point.
* This makes it possible to use {@code JavaMethodHandle} to create an anonymous
* inner class:
* <p><blockquote><pre>
* class Greeter extends JavaMethodHandle {
* // We can also do this with symbolic names and/or inner classes:
* MethodHandles.invoke(new JavaMethodHandle("yow") {
* void yow() { System.out.println("yow, world"); }
* });
* </pre></blockquote>
* <p>
* Here is similar lower-level code which works in terms of a bound method handle.
* <p><blockquote><pre>
* class Greeter {
* public void run() { System.out.println("hello, "+greetee); }
* private final String greetee;
* Greeter(String greetee) {
* super(RUN);
* this.greetee = greetee;
* }
* Greeter(String greetee) { this.greetee = greetee; }
* // the entry point function is computed once:
* private static final MethodHandle RUN
* = MethodHandles.findVirtual(MyMethodHandle.class, "run",
* = MethodHandles.findVirtual(Greeter.class, "run",
* MethodType.make(void.class));
* }
* // class Main { public static void main(String... av) { ...
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
* MethodHandle mh = greeter;
* MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
* mh.invoke(); // also prints "hello, world"
* </pre></blockquote>
* Note that the method handle must be separately created as a view on the base object.
* This increases footprint, complexity, and dynamic indirections.
* <p>
* In this example, the method {@code run} provides the entry point.
* The entry point need not be a constant value; it may be independently
* computed in each call to the constructor. The entry point does not
* even need to be a method on the Java method handle class, though
* that is the typical case.
* Here is a pure functional value expressed most concisely as an anonymous inner class:
* <p><blockquote><pre>
* // class Main { public static void main(String... av) { ...
* final String greetee = "world";
* MethodHandle greeter = new JavaMethodHandle("run") {
* private void run() { System.out.println("hello, "+greetee); }
* }
* greeter.invoke(); // prints "hello, world"
* </pre></blockquote>
* <p>
* Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
* and instantiated as an anonymous class. The data structure is a handle to 1-D array,
* with a specialized index type (long). It is created by inner class, and uses
* signature-polymorphic APIs throughout.
* <p><blockquote><pre>
* abstract class AssignableMethodHandle extends JavaMethodHandle {
* private final MethodHandle setter;
* public MethodHandle setter() { return setter; }
* public AssignableMethodHandle(String get, String set) {
* super(get);
* MethodType getType = this.type();
* MethodType setType = getType.insertParameterType(getType.parameterCount(), getType.returnType()).changeReturnType(void.class);
* this.setter = MethodHandles.publicLookup().bind(this, set, setType);
* }
* }
* // class Main { public static void main(String... av) { ...
* final Number[] stuff = { 123, 456 };
* AssignableMethodHandle stuffPtr = new AssignableMethodHandle("get", "set") {
* public Number get(long i) { return stuff[(int)i]; }
* public void set(long i, Object x) { stuff[(int)i] = x; }
* }
* int x = (Integer) stuffPtr.&lt;Number&gt;invoke(1L); // 456
* stuffPtr.setter().&lt;void&gt;invoke(0L, (Number) 789); // replaces 123 with 789
* </pre></blockquote>
* @see MethodHandle
* @author John Rose, JSR 292 EG
*/
......@@ -72,12 +148,87 @@ public abstract class JavaMethodHandle
// with a JVM change which moves the required hidden behavior onto this class.
extends sun.dyn.BoundMethodHandle
{
private static final Access IMPL_TOKEN = Access.getToken();
/**
* When creating a, pass in {@code entryPoint}, any method handle which
* can take the current object
* @param entryPoint
* When creating a {@code JavaMethodHandle}, the actual method handle
* invocation behavior will be delegated to the specified {@code entryPoint}.
* This may be any method handle which can take the newly constructed object
* as a leading parameter.
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be {@code entryPoint}, minus the leading argument.
* The leading argument will be bound to {@code this} on every method
* handle invocation.
* @param entryPoint the method handle to handle calls
*/
protected JavaMethodHandle(MethodHandle entryPoint) {
super(entryPoint, 0);
super(entryPoint);
}
/**
* Create a method handle whose entry point is a non-static method
* visible in the exact (most specific) class of
* the newly constructed object.
* <p>
* The method is specified by name and type, as if via this expression:
* {@code MethodHandles.lookup().findVirtual(this.getClass(), name, type)}.
* The class defining the method might be an anonymous inner class.
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be the given method handle type.
* A call to {@code this} will invoke the selected method.
* The receiver argument will be bound to {@code this} on every method
* handle invocation.
* <p>
* <i>Rationale:</i>
* Although this constructor may seem to be a mere luxury,
* it is not subsumed by the more general constructor which
* takes any {@code MethodHandle} as the entry point argument.
* In order to convert an entry point name to a method handle,
* the self-class of the object is required (in order to do
* the lookup). The self-class, in turn, is generally not
* available at the time of the constructor invocation,
* due to the rules of Java and the JVM verifier.
* One cannot call {@code this.getClass()}, because
* the value of {@code this} is inaccessible at the point
* of the constructor call. (Changing this would require
* change to the Java language, verifiers, and compilers.)
* In particular, this constructor allows {@code JavaMethodHandle}s
* to be created in combination with the anonymous inner class syntax.
* @param entryPointName the name of the entry point method
* @param type (optional) the desired type of the method handle
*/
protected JavaMethodHandle(String entryPointName, MethodType type) {
super(entryPointName, type, true);
}
/**
* Create a method handle whose entry point is a non-static method
* visible in the exact (most specific) class of
* the newly constructed object.
* <p>
* The method is specified only by name.
* There must be exactly one method of that name visible in the object class,
* either inherited or locally declared.
* (That is, the method must not be overloaded.)
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be the same as the type of the selected non-static method.
* The receiver argument will be bound to {@code this} on every method
* handle invocation.
* <p>ISSUE: This signature wildcarding feature does not correspond to
* any MethodHandles.Lookup API element. Can we eliminate it?
* Alternatively, it is useful for naming non-overloaded methods.
* Shall we make type arguments optional in the Lookup methods,
* throwing an error in cases of ambiguity?
* <p>
* For this method's rationale, see the documentation
* for {@link #JavaMethodHandle(String,MethodType)}.
* @param entryPointName the name of the entry point method
*/
protected JavaMethodHandle(String entryPointName) {
super(entryPointName, (MethodType) null, false);
}
}
......@@ -25,7 +25,9 @@
package java.dyn;
import java.dyn.MethodHandles.Lookup;
import java.util.WeakHashMap;
import sun.dyn.Access;
import sun.reflect.Reflection;
import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
......@@ -34,6 +36,8 @@ import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
* @author John Rose, JSR 292 EG
*/
public class Linkage {
private static final Access IMPL_TOKEN = Access.getToken();
private Linkage() {} // do not instantiate
/**
......@@ -53,19 +57,23 @@ public class Linkage {
* call to this method.
* <li>The given class is already fully initialized.
* <li>The given class is in the process of initialization, in another thread.
* <li>The same {@code CallSite} object has already been returned from
* a bootstrap method call to another {@code invokedynamic} call site.
* </ul>
* Because of these rules, a class may install its own bootstrap method in
* a static initializer.
* @param callerClass a class that may have {@code invokedynamic} sites
* @param bootstrapMethod the method to use to bootstrap all such sites
*/
public static
void registerBootstrapMethod(Class callerClass, MethodHandle mh) {
void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
Class callc = Reflection.getCallerClass(2);
checkBootstrapPrivilege(callc, callerClass, "registerBootstrapMethod");
checkBSM(mh);
checkBSM(bootstrapMethod);
synchronized (bootstrapMethods) {
if (bootstrapMethods.containsKey(callerClass))
throw new IllegalStateException("bootstrap method already declared in "+callerClass);
bootstrapMethods.put(callerClass, mh);
bootstrapMethods.put(callerClass, bootstrapMethod);
}
}
......@@ -88,8 +96,9 @@ public class Linkage {
public static
void registerBootstrapMethod(Class<?> runtime, String name) {
Class callc = Reflection.getCallerClass(2);
Lookup lookup = new Lookup(IMPL_TOKEN, callc);
MethodHandle bootstrapMethod =
MethodHandles.findStaticFrom(callc, runtime, name, BOOTSTRAP_METHOD_TYPE);
lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
// FIXME: exception processing wrong here
checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
......@@ -106,8 +115,9 @@ public class Linkage {
public static
void registerBootstrapMethod(String name) {
Class callc = Reflection.getCallerClass(2);
Lookup lookup = new Lookup(IMPL_TOKEN, callc);
MethodHandle bootstrapMethod =
MethodHandles.findStaticFrom(callc, callc, name, BOOTSTRAP_METHOD_TYPE);
lookup.findStatic(callc, name, BOOTSTRAP_METHOD_TYPE);
// FIXME: exception processing wrong here
checkBSM(bootstrapMethod);
Linkage.registerBootstrapMethod(callc, bootstrapMethod);
......@@ -116,8 +126,7 @@ public class Linkage {
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Report the bootstrap method registered for a given class.
* Returns null if the class has never yet registered a bootstrap method,
* or if the class has explicitly registered a null bootstrap method.
* Returns null if the class has never yet registered a bootstrap method.
* Only callers privileged to set the bootstrap method may inquire
* about it, because a bootstrap method is potentially a back-door entry
* point into its class.
......@@ -137,12 +146,12 @@ public class Linkage {
* {@code (Class, String, MethodType)} returning a {@code CallSite}.
*/
public static final MethodType BOOTSTRAP_METHOD_TYPE
= MethodType.make(CallSite.class,
Class.class, String.class, MethodType.class);
= MethodType.methodType(CallSite.class,
Class.class, String.class, MethodType.class);
private static final MethodType OLD_BOOTSTRAP_METHOD_TYPE
= MethodType.make(Object.class,
CallSite.class, Object[].class);
= MethodType.methodType(Object.class,
CallSite.class, Object[].class);
private static final WeakHashMap<Class, MethodHandle> bootstrapMethods =
new WeakHashMap<Class, MethodHandle>();
......@@ -173,8 +182,8 @@ public class Linkage {
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Invalidate all <code>invokedynamic</code> call sites associated
* with the given class.
* Invalidate all <code>invokedynamic</code> call sites in the bytecodes
* of any methods of the given class.
* (These are exactly those sites which report the given class
* via the {@link CallSite#callerClass()} method.)
* <p>
......
......@@ -88,7 +88,7 @@ public final class LinkagePermission extends BasicPermission {
/**
* Create a new LinkagePermission with the given name.
* The name is the symbolic name of the LinkagePermission, such as
* "registerBootstrapMethod", "invalidateClass.*", etc. An asterisk
* "registerBootstrapMethod", "invalidateCallerClass.*", etc. An asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match.
*
......
......@@ -30,6 +30,9 @@ package java.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 reference to the entry point of a method.
* <p>
......@@ -45,8 +48,9 @@ import sun.dyn.MethodHandleImpl;
* Every method handle appears as an object containing a method named
* <code>invoke</code>, whose signature exactly matches
* the method handle's type.
* A normal Java method call (using the <code>invokevirtual</code> instruction)
* can invoke this method from Java source code (if language support is present).
* A Java method call expression, which compiles to an
* <code>invokevirtual</code> instruction,
* can invoke this method from Java source code.
* <p>
* Every call to a method handle specifies an intended method type,
* which must exactly match the type of the method handle.
......@@ -57,6 +61,10 @@ import sun.dyn.MethodHandleImpl;
* The call fails with a {@link WrongMethodTypeException}
* if the method does not exist, even if there is an <code>invoke</code>
* method of a closely similar signature.
* As with other kinds
* of methods in the JVM, signature matching during method linkage
* is exact, and does not allow for language-level implicit conversions
* such as {@code String} to {@code Object} or {@code short} to {@code int}.
* <p>
* A method handle is an unrestricted capability to call a method.
* A method handle can be formed on a non-public method by a class
......@@ -74,6 +82,15 @@ import sun.dyn.MethodHandleImpl;
* (after resolving symbolic type names) must exactly match the method type
* of the target method.
* <p>
* Every <code>invoke</code> method always throws {@link Exception},
* 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 Exception}, or else must catch all checked exceptions locally.
* <p>
* Bytecode in an extended JVM can directly obtain a method handle
* for any accessible method from a <code>ldc</code> instruction
* which refers to a <code>CONSTANT_Methodref</code> or
......@@ -97,6 +114,59 @@ import sun.dyn.MethodHandleImpl;
* 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</code> instruction to the same method.
* <p>
* Here are some examples of usage:
* <p><blockquote><pre>
* Object x, y; String s; int i;
* MethodType mt; MethodHandle mh;
* MethodHandles.Lookup lookup = MethodHandles.lookup();
* // mt is {(char,char) =&gt; String}
* mt = MethodType.make(String.class, char.class, char.class);
* mh = lookup.findVirtual(String.class, "replace", mt);
* // (Ljava/lang/String;CC)Ljava/lang/String;
* s = mh.&lt;String&gt;invoke("daddy",'d','n');
* assert(s.equals("nanny"));
* // weakly typed invocation (using MHs.invoke)
* s = (String) MethodHandles.invoke(mh, "sappy", 'p', 'v');
* assert(s.equals("savvy"));
* // mt is {Object[] =&gt; List}
* mt = MethodType.make(java.util.List.class, Object[].class);
* mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
* // mt is {(Object,Object,Object) =&gt; Object}
* mt = MethodType.makeGeneric(3);
* mh = MethodHandles.collectArguments(mh, mt);
* // mt is {(Object,Object,Object) =&gt; Object}
* // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
* x = mh.invoke((Object)1, (Object)2, (Object)3);
* assert(x.equals(java.util.Arrays.asList(1,2,3)));
* // mt is { =&gt; int}
* mt = MethodType.make(int.class);
* mh = lookup.findVirtual(java.util.List.class, "size", mt);
* // (Ljava/util/List;)I
* i = mh.&lt;int&gt;invoke(java.util.Arrays.asList(1,2,3));
* assert(i == 3);
* </pre></blockquote>
* Each of the above calls generates a single invokevirtual instruction
* with the name {@code invoke} and the type descriptors indicated in the comments.
* The argument types are taken directly from the actual arguments,
* while the return type is taken from the type parameter.
* (This type parameter may be a primitive, and it defaults to {@code Object}.)
* <p>
* <em>A note on generic typing:</em> Method handles do not represent
* their function types in terms of Java parameterized (generic) types,
* because there are three mismatches between function types and parameterized
* Java types.
* <ol>
* <li>Method types range over all possible arities,
* from no arguments to an arbitrary number of arguments.
* Generics are not variadic, and so cannot represent this.</li>
* <li>Method types can specify arguments of primitive types,
* which Java generic types cannot range over.</li>
* <li>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.</li>
* </ol>
*
* @see MethodType
* @see MethodHandles
......@@ -107,17 +177,19 @@ public abstract class MethodHandle
// with a JVM change which moves the required hidden state onto this class.
extends MethodHandleImpl
{
// interface MethodHandle<T extends MethodType<R,A...>>
// { T type(); <R,A...> public R invoke(A...); }
private static Access IMPL_TOKEN = Access.getToken();
final private MethodType type;
// interface MethodHandle<R throws X extends Exception,A...>
// { MethodType<R throws X,A...> type(); public R invoke(A...) throws X; }
private MethodType type;
/**
* Report the type of this method handle.
* Every invocation of this method handle must exactly match this type.
* @return the method handle type
*/
public MethodType type() {
public final MethodType type() {
return type;
}
......@@ -130,6 +202,369 @@ public abstract class MethodHandle
*/
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); }
});
}
/** The string of a direct method handle is the simple name of its target method.
* The string of an adapter or bound method handle is the string of its
* target method handle.
* The string of a Java method handle is the string of its entry point method,
* unless the Java method handle overrides the toString method.
*/
@Override
public String toString() {
return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
}
//// First draft of the "Method Handle Kernel API" discussed at the JVM Language Summit, 9/2009.
//// Implementations here currently delegate to statics in MethodHandles. Some of those statics
//// will be deprecated. Others will be kept as "algorithms" to supply degrees of freedom
//// not present in the Kernel API.
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform an exact invocation. The signature at the call site of {@code invokeExact} must
* exactly match this method handle's {@code type}.
* No conversions are allowed on arguments or return values.
* <em>This is not yet implemented, pending required compiler and JVM support.</em>
*/
public final <T> T invokeExact(Object... arguments) throws Throwable {
// This is an approximate implementation, which discards the caller's signature and refuses the call.
throw new InternalError("not yet implemented");
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform a generic invocation. The signature at the call site of {@code invokeExact} must
* have the same arity as this method handle's {@code type}.
* The same conversions are allowed on arguments or return values as are supported by
* by {@link MethodHandles#convertArguments}.
* If the call site signature exactly matches this method handle's {@code type},
* the call proceeds as if by {@link #invokeExact}.
* <em>This is not fully implemented, pending required compiler and JVM support.</em>
*/
// This is an approximate implementation, which discards the caller's signature.
// When it is made signature polymorphic, the overloadings will disappear.
public final <T> T invokeGeneric() throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this);
}
public final <T> T invokeGeneric(Object a0) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0);
}
public final <T> T invokeGeneric(Object a0, Object a1) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7, a8);
}
public final <T> T invokeGeneric(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable {
MethodHandle invoker = invokers(this.type()).genericInvoker();
return invoker.<T>invoke(this, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform a varargs invocation, passing the arguments in the given array
* to the method handle, as if via {@link #invokeGeneric} from a call site
* which mentions only the type {@code Object}, and whose arity is the length
* of the argument array.
* <p>
* The length of the arguments array must equal the parameter count
* of the target's type.
* The arguments array is spread into separate arguments.
* <p>
* In order to match the type of the target, the following argument
* conversions are applied as necessary:
* <ul>
* <li>reference casting
* <li>unboxing
* </ul>
* The following conversions are not applied:
* <ul>
* <li>primitive conversions (e.g., {@code byte} to {@code int}
* <li>varargs conversions other than the initial spread
* <li>any application-specific conversions (e.g., string to number)
* </ul>
* The result returned by the call is boxed if it is a primitive,
* or forced to null if the return type is void.
* <p>
* This call is equivalent to the following code:
* <p><blockquote><pre>
* MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true);
* Object result = invoker.invoke(this, arguments);
* </pre></blockquote>
* @param arguments the arguments to pass to the target
* @return the result returned by the target
* @see MethodHandles#genericInvoker
*/
public final Object invokeVarargs(Object[] arguments) throws Throwable {
int argc = arguments == null ? 0 : arguments.length;
MethodType type = type();
if (argc <= 10) {
MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
switch (argc) {
case 0: return invoker.invoke(this);
case 1: return invoker.invoke(this,
arguments[0]);
case 2: return invoker.invoke(this,
arguments[0], arguments[1]);
case 3: return invoker.invoke(this,
arguments[0], arguments[1], arguments[2]);
case 4: return invoker.invoke(this,
arguments[0], arguments[1], arguments[2],
arguments[3]);
case 5: return invoker.invoke(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4]);
case 6: return invoker.invoke(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5]);
case 7: return invoker.invoke(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6]);
case 8: return invoker.invoke(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7]);
case 9: return invoker.invoke(this,
arguments[0], arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5],
arguments[6], arguments[7], arguments[8]);
case 10: return invoker.invoke(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 = MethodHandles.invokers(type).varargsInvoker(0);
return invoker.invoke(this, arguments);
}
/** Equivalent to {@code invokeVarargs(arguments.toArray())}. */
public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable {
return invokeVarargs(arguments.toArray());
}
/* --- this is intentionally NOT a javadoc yet ---
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce an adapter method handle which adapts the type of the
* current 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 confess a type
* which is equal to the desired new type.
* <p>
* If the original type and new type are equal, returns {@code this}.
* <p>
* 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:
* <ul>
* <li>If T0 and T1 are references, and T1 is not an interface type,
* then a cast to T1 is applied.
* (The types do not need to be related in any particular way.)
* <li>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.)
* <li>If T0 and T1 are primitives, then a Java casting
* conversion (JLS 5.5) is applied, if one exists.
* <li>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.
* <li>If T0 is a primitive and T1 a reference, a boxing
* conversion is applied if one exists, possibly followed by
* an reference conversion to a superclass.
* T1 must be a wrapper class or a supertype of one.
* If T1 is a wrapper class, T0 is converted if necessary
* to T1's primitive type by one of the preceding conversions.
* Otherwise, T0 is boxed, and its wrapper converted to T1.
* <li>If T0 is a reference and T1 a primitive, an unboxing
* conversion is applied if one exists, possibly preceded by
* a reference conversion to a wrapper class.
* T0 must be a wrapper class or a supertype of one.
* If T0 is a wrapper class, its primitive value is converted
* if necessary to T1 by one of the preceding conversions.
* Otherwise, T0 is converted directly to the wrapper type for T1,
* which is then unboxed.
* <li>If the return type T1 is void, any returned value is discarded
* <li>If the return type T0 is void and T1 a reference, a null value is introduced.
* <li>If the return type T0 is void and T1 a primitive, a zero value is introduced.
* </ul>
* <p>
*/
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce an adapter method handle which adapts the type of the
* current 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 confess a type
* which is equal to the desired new type.
* <p>
* If the original type and new type are equal, returns {@code this}.
* <p>
* This method is equivalent to {@link MethodHandles#convertArguments}.
* @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 IllegalArgumentException if the conversion cannot be made
* @see MethodHandles#convertArguments
*/
public final MethodHandle asType(MethodType newType) {
return MethodHandles.convertArguments(this, newType);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts, as its <i>target</i>,
* the current method handle. The type of the adapter will be
* the same as the type of the target, except that all but the first
* {@code keepPosArgs} parameters of the target's type are replaced
* by a single array parameter of type {@code Object[]}.
* Thus, if {@code keepPosArgs} is zero, the adapter will take all
* arguments in a single object array.
* <p>
* 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
* (as if by {@link MethodHandles#convertArguments})
* 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.
* <p>
* 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 keepPosArgs the number of leading positional arguments to preserve
* @return a new method handle which spreads its final argument,
* before calling the original method handle
* @throws IllegalArgumentException if target does not have at least
* {@code keepPosArgs} parameter types
*/
public final MethodHandle asSpreader(int keepPosArgs) {
MethodType oldType = type();
int nargs = oldType.parameterCount();
MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
newType = newType.insertParameterTypes(keepPosArgs, Object[].class);
return MethodHandles.spreadArguments(this, newType);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts, as its <i>target</i>,
* the current method handle. The type of the adapter will be
* the same as the type of the target, except that a single trailing
* array parameter of type {@code Object[]} is replaced by
* {@code spreadArrayArgs} parameters of type {@code Object}.
* <p>
* When called, the adapter replaces its trailing {@code spreadArrayArgs}
* arguments by a single new {@code Object} array, whose elements
* comprise (in order) the replaced arguments.
* Finally the target is called.
* What the target eventually returns is returned unchanged by the adapter.
* <p>
* (The array may also be a shared constant when {@code spreadArrayArgs} is zero.)
* @param spreadArrayArgs the number of arguments to spread from the trailing array
* @return a new method handle which collects some trailing argument
* into an array, before calling the original method handle
* @throws IllegalArgumentException if the last argument of the target
* is not {@code Object[]}
* @throws IllegalArgumentException if {@code spreadArrayArgs} is not
* a legal array size
* @deprecated Provisional and unstable; use {@link MethodHandles#collectArguments}.
*/
public final MethodHandle asCollector(int spreadArrayArgs) {
MethodType oldType = type();
int nargs = oldType.parameterCount();
MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
newType = newType.insertParameterTypes(nargs-1, MethodType.genericMethodType(spreadArrayArgs).parameterArray());
return MethodHandles.collectArguments(this, newType);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which binds the given argument
* to the current method handle as <i>target</i>.
* 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.
* <p>
* 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.
* <p>
* 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
* @deprecated Provisional and unstable; use {@link MethodHandles#insertArguments}.
*/
public final MethodHandle bindTo(Object x) {
return MethodHandles.insertArguments(this, 0, x);
}
}
......@@ -34,6 +34,7 @@ import sun.dyn.util.Wrapper;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import sun.dyn.Invokers;
......@@ -44,17 +45,14 @@ import static sun.dyn.MemberName.newNoAccessException;
/**
* Fundamental operations and utilities for MethodHandle.
* They fall into several categories:
* <ul>
* <li>Reifying methods and fields. This is subject to access checks.
* <li>Invoking method handles on dynamically typed arguments and/or varargs arrays.
* <li>Combining or transforming pre-existing method handles into new ones.
* <li>Miscellaneous emulation of common JVM operations or control flow patterns.
* </ul>
* <p>
* <em>API Note:</em> The matching of method types in this API cannot
* be completely checked by Java's generic type system for three reasons:
* <ol>
* <li>Method types range over all possible arities,
* from no arguments to an arbitrary number of arguments.
* Generics are not variadic, and so cannot represent this.</li>
* <li>Method types can specify arguments of primitive types,
* which Java generic types cannot range over.</li>
* <li>Method types can optionally specify varargs (ellipsis).</li>
* </ol>
* @author John Rose, JSR 292 EG
*/
public class MethodHandles {
......@@ -68,12 +66,22 @@ public class MethodHandles {
//// Method handle creation from ordinary methods.
/** Create a {@link Lookup} lookup object on the caller.
*
*/
public static Lookup lookup() {
return new Lookup();
}
/** Version of lookup which is trusted minimally.
* It can only be used to create method handles to
* publicly accessible members.
*/
public static Lookup publicLookup() {
return Lookup.PUBLIC_LOOKUP;
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* A factory object for creating method handles, when the creation
* requires access checking. Method handles do not perform
* access checks when they are called; this is a major difference
......@@ -121,7 +129,8 @@ public class MethodHandles {
/** Which class is performing the lookup? It is this class against
* which checks are performed for visibility and access permissions.
* <p>
* This value is null if and only if this lookup is {@link #PUBLIC_LOOKUP}.
* This value is null if and only if this lookup was produced
* by {@link MethodHandles#publicLookup}.
*/
public Class<?> lookupClass() {
return lookupClass;
......@@ -135,23 +144,46 @@ public class MethodHandles {
* an access$N method.
*/
Lookup() {
Class caller = getCallerClassAtEntryPoint();
// make sure we haven't accidentally picked up this class:
checkUnprivilegedlookupClass(caller);
this.lookupClass = caller;
this(IMPL_TOKEN, getCallerClassAtEntryPoint());
}
Lookup(Access token, Class<?> lookupClass) {
// make sure we haven't accidentally picked up a privileged class:
checkUnprivilegedlookupClass(lookupClass);
this.lookupClass = lookupClass;
}
/**
* Create a lookup on the specified class.
* The result is guaranteed to have no more access privileges
* than the original.
*/
public Lookup in(Class<?> newLookupClass) {
if (this == PUBLIC_LOOKUP) return PUBLIC_LOOKUP;
if (newLookupClass == null) return PUBLIC_LOOKUP;
if (newLookupClass == lookupClass) return this;
if (this != IMPL_LOOKUP) {
if (!VerifyAccess.isSamePackage(lookupClass, newLookupClass))
throw newNoAccessException(new MemberName(newLookupClass), this);
checkUnprivilegedlookupClass(newLookupClass);
}
return new Lookup(newLookupClass);
}
private Lookup(Class<?> lookupClass) {
this.lookupClass = lookupClass;
}
// Make sure outer class is initialized first.
static { IMPL_TOKEN.getClass(); }
private static final Class<?> PUBLIC_ONLY = sun.dyn.empty.Empty.class;
/** Version of lookup which is trusted minimally.
* It can only be used to create method handles to
* publicly accessible members.
*/
public static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_ONLY);
static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_ONLY);
/** Package-private version of lookup which is trusted. */
static final Lookup IMPL_LOOKUP = new Lookup(null);
......@@ -178,12 +210,16 @@ public class MethodHandles {
// 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
// 2: Lookup.<init>, 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);
}
/**
* Produce 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 {@linkplain #findVirtual} or {@linkplain #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.
......@@ -196,10 +232,11 @@ public class MethodHandles {
*/
public
MethodHandle findStatic(Class<?> defc, String name, MethodType type) throws NoAccessException {
MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookupClass);
checkStatic(true, method, lookupClass);
MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookupClass());
VerifyAccess.checkName(method, this);
checkStatic(true, method, this);
//throw NoSuchMethodException
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClass);
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClass());
}
/**
......@@ -228,9 +265,10 @@ public class MethodHandles {
* @exception NoAccessException if the method does not exist or access checking fails
*/
public MethodHandle findVirtual(Class<?> defc, String name, MethodType type) throws NoAccessException {
MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), true, lookupClass);
checkStatic(false, method, lookupClass);
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass);
MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), true, lookupClass());
VerifyAccess.checkName(method, this);
checkStatic(false, method, this);
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass());
}
/**
......@@ -259,15 +297,17 @@ public class MethodHandles {
*/
public MethodHandle findSpecial(Class<?> defc, String name, MethodType type,
Class<?> specialCaller) throws NoAccessException {
checkSpecialCaller(specialCaller, lookupClass);
MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), false, specialCaller);
checkStatic(false, method, lookupClass);
checkSpecialCaller(specialCaller, this);
Lookup slookup = this.in(specialCaller);
MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type), false, slookup.lookupClass());
VerifyAccess.checkName(method, this);
checkStatic(false, method, this);
if (name.equals("<init>")) {
throw newNoAccessException("cannot directly invoke a constructor", method, null);
} else if (defc.isInterface() || !defc.isAssignableFrom(specialCaller)) {
throw newNoAccessException("method must be in a superclass of lookup class", method, lookupClass);
throw newNoAccessException("method must be in a superclass of lookup class", method, slookup.lookupClass());
}
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, specialCaller);
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, slookup.lookupClass());
}
/**
......@@ -275,13 +315,19 @@ public class MethodHandles {
* 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.
* The given receiver will be bound into the method handle.
* 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.
* <p>
* Equivalent to the following expression:
* This is equivalent to the following expression:
* <code>
* {@link #insertArgument}({@link #findVirtual}(defc, name, type), receiver)
* {@link #insertArguments}({@link #findVirtual}(defc, name, type), receiver)
* </code>
* 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.
* @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
......@@ -292,16 +338,18 @@ public class MethodHandles {
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoAccessException {
Class<? extends Object> rcvc = receiver.getClass(); // may get NPE
MemberName reference = new MemberName(rcvc, name, type);
MemberName method = IMPL_NAMES.resolveOrFail(reference, true, lookupClass);
checkStatic(false, method, lookupClass);
MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass);
MemberName method = IMPL_NAMES.resolveOrFail(reference, true, lookupClass());
VerifyAccess.checkName(method, this);
checkStatic(false, method, this);
MethodHandle dmh = MethodHandleImpl.findMethod(IMPL_TOKEN, method, true, lookupClass());
MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, dmh, receiver);
if (bmh == null)
throw newNoAccessException(method, lookupClass);
throw newNoAccessException(method, this);
return bmh;
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Make a direct method handle to <i>m</i>, if the lookup class has permission.
* If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
* If <i>m</i> is virtual, overriding is respected on every call.
......@@ -316,10 +364,11 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflect(Method m) throws NoAccessException {
return unreflectImpl(new MemberName(m), m.isAccessible(), true, lookupClass);
return unreflectImpl(new MemberName(m), m.isAccessible(), true, false, this);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle for a reflected method.
* It will bypass checks for overriding methods on the receiver,
* as if by the {@code invokespecial} instruction.
......@@ -333,37 +382,41 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws NoAccessException {
checkSpecialCaller(specialCaller, lookupClass);
checkSpecialCaller(specialCaller, this);
Lookup slookup = this.in(specialCaller);
MemberName mname = new MemberName(m);
checkStatic(false, mname, lookupClass);
return unreflectImpl(mname, m.isAccessible(), false, specialCaller);
checkStatic(false, mname, this);
return unreflectImpl(mname, m.isAccessible(), false, false, slookup);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle for a reflected constructor.
* The type of the method handle will be that of the 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.
* <p>
* If the constructor'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.
* access checking is performed immediately on behalf of the lookup class.
* @param ctor the reflected constructor
* @return a method handle which can invoke the reflected constructor
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectConstructor(Constructor ctor) throws NoAccessException {
MemberName m = new MemberName(ctor);
return unreflectImpl(m, ctor.isAccessible(), false, lookupClass);
return unreflectImpl(m, ctor.isAccessible(), false, false, this);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce 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. Its sole argument will be the field's containing class
* (but only if it is non-static).
* 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
......@@ -371,16 +424,18 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectGetter(Field f) throws NoAccessException {
return MethodHandleImpl.accessField(IMPL_TOKEN, new MemberName(f), false, lookupClass);
MemberName m = new MemberName(f);
return unreflectImpl(m, f.isAccessible(), false, false, this);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving write access to a reflected field.
* The type of the method handle will have a void return type.
* Its last argument will be the field's value type.
* Its other argument will be the field's containing class
* (but only if it is non-static).
* 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
......@@ -388,59 +443,75 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSetter(Field f) throws NoAccessException {
return MethodHandleImpl.accessField(IMPL_TOKEN, new MemberName(f), true, lookupClass);
MemberName m = new MemberName(f);
return unreflectImpl(m, f.isAccessible(), false, true, this);
}
}
static /*must not be public*/
MethodHandle findStaticFrom(Class<?> lookupClass,
MethodHandle findStaticFrom(Lookup lookup,
Class<?> defc, String name, MethodType type) throws NoAccessException {
MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookupClass);
checkStatic(true, method, lookupClass);
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookupClass);
MemberName method = IMPL_NAMES.resolveOrFail(new MemberName(defc, name, type, Modifier.STATIC), true, lookup.lookupClass());
VerifyAccess.checkName(method, lookup);
checkStatic(true, method, lookup);
return MethodHandleImpl.findMethod(IMPL_TOKEN, method, false, lookup.lookupClass());
}
static void checkStatic(boolean wantStatic, MemberName m, Class<?> lookupClass) {
static void checkStatic(boolean wantStatic, MemberName m, Lookup lookup) {
if (wantStatic != m.isStatic()) {
String message = wantStatic ? "expected a static method" : "expected a non-static method";
throw newNoAccessException(message, m, lookupClass);
throw newNoAccessException(message, m, lookup.lookupClass());
}
}
static void checkSpecialCaller(Class<?> specialCaller, Class<?> lookupClass) {
if (lookupClass == Lookup.IMPL_LOOKUP.lookupClass())
static void checkSpecialCaller(Class<?> specialCaller, Lookup lookup) {
if (lookup == Lookup.IMPL_LOOKUP)
return; // privileged action
if (lookupClass == null || // public-only access
!VerifyAccess.isSamePackageMember(specialCaller, lookupClass))
throw newNoAccessException("no private access", new MemberName(specialCaller), lookupClass);
assert(lookup.lookupClass() != null);
if (!VerifyAccess.isSamePackageMember(specialCaller, lookup.lookupClass()))
throw newNoAccessException("no private access", new MemberName(specialCaller), lookup.lookupClass());
}
// Helper for creating handles on reflected methods and constructors.
static MethodHandle unreflectImpl(MemberName m, boolean isAccessible,
boolean doDispatch, Class<?> lookupClass) {
MethodType mtype = m.getInvocationType();
boolean doDispatch, boolean isSetter, Lookup lookup) {
MethodType narrowMethodType = null;
Class<?> defc = m.getDeclaringClass();
boolean isSpecialInvoke = m.isInvocable() && !doDispatch;
int mods = m.getModifiers();
if (m.isStatic()) {
if (!isAccessible &&
VerifyAccess.isAccessible(defc, mods, false, lookupClass) == null)
throw newNoAccessException(m, lookupClass);
VerifyAccess.isAccessible(defc, mods, lookup.lookupClass(), false) == null)
throw newNoAccessException(m, lookup);
} else {
Class<?> constraint;
if (isAccessible) {
// abbreviated access check for "unlocked" method
constraint = doDispatch ? defc : lookupClass;
constraint = doDispatch ? defc : lookup.lookupClass();
} else {
constraint = VerifyAccess.isAccessible(defc, mods, doDispatch, lookupClass);
constraint = VerifyAccess.isAccessible(defc, mods, lookup.lookupClass(), isSpecialInvoke);
}
if (constraint == null) {
throw newNoAccessException(m, lookup);
}
if (constraint != defc && !constraint.isAssignableFrom(defc)) {
if (!defc.isAssignableFrom(constraint))
throw newNoAccessException("receiver must be in caller class", m, lookupClass);
mtype = mtype.changeParameterType(0, constraint);
throw newNoAccessException("receiver must be in caller class", m, lookup.lookupClass());
if (m.isInvocable())
narrowMethodType = m.getInvocationType().changeParameterType(0, constraint);
else if (m.isField())
narrowMethodType = (!isSetter
? MethodType.methodType(m.getFieldType(), constraint)
: MethodType.methodType(void.class, constraint, m.getFieldType()));
}
}
return MethodHandleImpl.findMethod(IMPL_TOKEN, m, doDispatch, lookupClass);
if (m.isInvocable())
return MethodHandleImpl.findMethod(IMPL_TOKEN, m, doDispatch, lookup.lookupClass());
else if (m.isField())
return MethodHandleImpl.accessField(IMPL_TOKEN, m, isSetter, lookup.lookupClass());
else
throw new InternalError();
}
/**
......@@ -472,138 +543,104 @@ public class MethodHandles {
return MethodHandleImpl.accessArrayElement(IMPL_TOKEN, arrayClass, true);
}
/// method handle invocation (reflective style)
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Call the {@code invoke} method of a given method handle,
* with arguments that exactly match the parameter types of the method handle.
* The length of the arguments array must equal the parameter count
* of the target's type.
* The arguments array is spread into separate arguments, and
* basic reference and unboxing conversions are applied.
* <p>
* In order to match the type of the target, the following argument
* conversions are applied as necessary:
* <ul>
* <li>reference casting
* <li>unboxing
* </ul>
* The following conversions are not applied:
* <ul>
* <li>primitive conversions (e.g., {@code byte} to {@code int}
* <li>varargs conversions other than the initial spread
* <li>any application-specific conversions (e.g., string to number)
* </ul>
* The result returned by the call is boxed if it is a primitive,
* or forced to null if the return type is void.
* <p>
* This call is a convenience method for the following code:
* <pre>
* MethodHandle invoker = MethodHandles.genericInvoker(target.type(), 0, true);
* Object result = invoker.invoke(arguments);
* </pre>
* @param target the method handle to invoke
* @param arguments the arguments to pass to the target
* @return the result returned by the target
* @deprecated Alias for MethodHandle.invokeVarargs.
*/
@Deprecated
public static
Object invoke(MethodHandle target, Object... arguments) {
int argc = arguments == null ? 0 : arguments.length;
MethodType type = target.type();
if (argc <= 4) {
MethodHandle invoker = invokers(type).genericInvoker();
switch (argc) {
case 0: return invoker.<Object>invoke(target);
case 1: return invoker.<Object>invoke(target,
arguments[0]);
case 2: return invoker.<Object>invoke(target,
arguments[0], arguments[1]);
case 3: return invoker.<Object>invoke(target,
arguments[0], arguments[1], arguments[2]);
case 4: return invoker.<Object>invoke(target,
arguments[0], arguments[1], arguments[2], arguments[3]);
}
}
MethodHandle invoker = invokers(type).varargsInvoker();
return invoker.<Object>invoke(target, arguments);
Object invokeVarargs(MethodHandle target, Object... arguments) throws Throwable {
return target.invokeVarargs(arguments);
}
/**
* @deprecated Alias for MethodHandle.invokeVarargs.
*/
@Deprecated
public static
Object invoke_0(MethodHandle target) {
MethodHandle invoker = invokers(target.type()).genericInvoker();
return invoker.<Object>invoke(target);
}
public static
Object invoke_1(MethodHandle target, Object a0) {
MethodHandle invoker = invokers(target.type()).genericInvoker();
return invoker.<Object>invoke(target, a0);
}
public static
Object invoke_2(MethodHandle target, Object a0, Object a1) {
MethodHandle invoker = invokers(target.type()).genericInvoker();
return invoker.<Object>invoke(target, a0, a1);
}
public static
Object invoke_3(MethodHandle target, Object a0, Object a1, Object a2) {
MethodHandle invoker = invokers(target.type()).genericInvoker();
return invoker.<Object>invoke(target, a0, a1, a2);
}
public static
Object invoke_4(MethodHandle target, Object a0, Object a1, Object a2, Object a3) {
MethodHandle invoker = invokers(target.type()).genericInvoker();
return invoker.<Object>invoke(target, a0, a1, a2, a3);
Object invoke(MethodHandle target, Object... arguments) throws Throwable {
return target.invokeVarargs(arguments);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Give a method handle which will invoke any method handle of the
* Produce a method handle which will invoke any method handle of the
* given type on a standard set of {@code Object} type arguments.
* The the resulting invoker will be a method handle with the following
* The resulting invoker will be a method handle with the following
* arguments:
* <ul>
* <li>a single {@code MethodHandle} target
* <li>zero or more {@code Object} values
* <li>an optional {@code Object[]} array containing more arguments
* <li>zero or more {@code Object} values (one for each argument in {@code type})
* </ul>
* The invoker will spread the varargs array (if present), apply
* reference casts as necessary, and unbox primitive arguments.
* The invoker will apply reference casts as necessary and unbox primitive arguments,
* as if by {@link #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.
* <p>
* This is a convenience method equivalent to the following code:
* <pre>
* This method is equivalent to the following code (though it may be more efficient):
* <p><blockquote><pre>
* MethodHandle invoker = exactInvoker(type);
* MethodType genericType = MethodType.makeGeneric(objectArgCount, varargs);
* MethodType genericType = type.generic();
* genericType = genericType.insertParameterType(0, MethodHandle.class);
* if (!varargs)
* return convertArguments(invoker, genericType);
* else
* return spreadArguments(invoker, genericType);
* </pre>
* return convertArguments(invoker, genericType);
* </pre></blockquote>
* @param type the type of target methods which the invoker will apply to
* @return a method handle suitable for invoking any method handle of the given type
*/
static public
MethodHandle genericInvoker(MethodType type) {
return invokers(type).genericInvoker();
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which will invoke any method handle of the
* given 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:
* <ul>
* <li>a single {@code MethodHandle} target
* <li>zero or more {@code Object} values (counted by {@code objectArgCount})
* <li>an {@code Object[]} array containing more arguments
* </ul>
* The invoker will spread the varargs array, apply
* reference casts as necessary, and unbox 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.
* <p>
* This method is equivalent to the following code (though it may be more efficient):
* <p><blockquote><pre>
* MethodHandle invoker = exactInvoker(type);
* MethodType vaType = MethodType.makeGeneric(objectArgCount, true);
* vaType = vaType.insertParameterType(0, MethodHandle.class);
* return spreadArguments(invoker, vaType);
* </pre></blockquote>
* @param type the desired target type
* @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
* @param varargs if true, the invoker will accept a final {@code Object[]} argument
* @return a method handle suitable for invoking any method handle of the given type
*/
static public
MethodHandle genericInvoker(MethodType type, int objectArgCount, boolean varargs) {
return invokers(type).genericInvoker();
MethodHandle varargsInvoker(MethodType type, int objectArgCount) {
if (objectArgCount < 0 || objectArgCount > type.parameterCount())
throw new IllegalArgumentException("bad argument count "+objectArgCount);
return invokers(type).varargsInvoker(objectArgCount);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Give a method handle which will take a invoke any method handle of the
* Produce a method handle which will take a invoke any method handle of the
* given type. 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}.
* <p>
* This is a convenience method equivalent to the following code:
* <pre>
* MethodHandles.lookup().findVirtual(MethodHandle.class, "invoke", type);
* </pre>
* This method is equivalent to the following code (though it may be more efficient):
* <p><blockquote><pre>
* lookup().findVirtual(MethodHandle.class, "invoke", type);
* </pre></blockquote>
* @param type the desired target type
* @return a method handle suitable for invoking any method handle of the given type
*/
......@@ -612,7 +649,30 @@ public class MethodHandles {
return invokers(type).exactInvoker();
}
static private Invokers invokers(MethodType type) {
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle equivalent to an invokedynamic instruction
* which has been linked to the given call site.
* Along with {@link Lookup#findVirtual}, {@link Lookup#findStatic},
* and {@link Lookup#findSpecial}, this completes the emulation
* of the JVM's {@code invoke} instructions.
* <p>This method is equivalent to the following code:
* <p><blockquote><pre>
* MethodHandle getTarget, invoker, result;
* getTarget = lookup().bind(site, "getTarget", methodType(MethodHandle.class));
* invoker = exactInvoker(site.type());
* result = foldArguments(invoker, getTarget)
* </pre></blockquote>
* @return a method handle which always invokes the call site's target
*/
public static
MethodHandle dynamicInvoker(CallSite site) {
MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, CallSite.GET_TARGET, site);
MethodHandle invoker = exactInvoker(site.type());
return foldArguments(invoker, getTarget);
}
static Invokers invokers(MethodType type) {
return MethodTypeImpl.invokers(IMPL_TOKEN, type);
}
......@@ -688,14 +748,11 @@ public class MethodHandles {
/// method handle modification (creation from other method handles)
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
* given method handle to a new type, by pairwise argument conversion,
* and/or varargs conversion.
* The original type and new type must have the same number of
* arguments, or else one or both them the must be varargs types.
* 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 confess a type
* which is equal to the desired new type, with any varargs property erased.
* which is equal to the desired new type.
* <p>
* If the original type and new type are equal, returns target.
* <p>
......@@ -703,26 +760,15 @@ public class MethodHandles {
* 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.
* <p>
* If an ordinary (non-varargs) parameter of the new type is
* to be boxed in a varargs parameter of the old type of type T1[],
* then T1 is the element type of the varargs array.
* Otherwise, if a varargs parameter of the new type of type T0[]
* is to be spread into one or more outgoing old type parameters,
* then T0 is the element type of the
* If the new type is varargs and the old type is not, the varargs
* argument will be checked and must be a non-null array of exactly
* the right length. If there are no parameters in the old type
* corresponding to the new varargs parameter, the varargs argument
* is also allowed to be null.
* <p>
* Given those types T0, T1, one of the following conversions is applied
* if possible:
* <ul>
* <li>If T0 and T1 are references, then a cast to T2 is applied,
* where T2 is Object if T1 is an interface, else T1.
* (The types do not need to be related in any particular way.
* The treatment of interfaces follows the usage of the bytecode verifier.)
* <li>If T0 and T1 are references, and T1 is not an interface type,
* then a cast to T1 is applied.
* (The types do not need to be related in any particular way.)
* <li>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.)
* <li>If T0 and T1 are primitives, then a Java casting
* conversion (JLS 5.5) is applied, if one exists.
* <li>If T0 and T1 are primitives and one is boolean,
......@@ -745,16 +791,17 @@ public class MethodHandles {
* if necessary to T1 by one of the preceding conversions.
* Otherwise, T0 is converted directly to the wrapper type for T1,
* which is then unboxed.
* <li>If T1 is void, any returned value is discarded
* <li>If T0 is void and T1 a reference, a null value is introduced.
* <li>If T0 is void and T1 a primitive, a zero value is introduced.
* <li>If the return type T1 is void, any returned value is discarded
* <li>If the return type T0 is void and T1 a reference, a null value is introduced.
* <li>If the return type T0 is void and T1 a primitive, a zero value is introduced.
* </ul>
* @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 WrongMethodTypeException if the conversion cannot be made
* @throws IllegalArgumentException if the conversion cannot be made
* @see MethodHandle#asType
*/
public static
MethodHandle convertArguments(MethodHandle target, MethodType newType) {
......@@ -872,23 +919,17 @@ public class MethodHandles {
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
* given method handle to a new type, by collecting a series of
* trailing arguments into an array.
* The resulting method handle is guaranteed to confess a type
* which is equal to the desired new type.
* trailing arguments as elements to a single argument array.
* <p>
* This method is inverse to {@link #spreadArguments}.
* This method may be used as an inverse to {@link #spreadArguments}.
* The final parameter type of the old type must be an array type T[],
* which is the type of what is called the <i>spread</i> argument.
* The trailing arguments of the new type which correspond to
* the spread argument are all converted to type T and collected
* into an array before the original method is called.
* <p>
* ISSUE: Unify this with combineArguments. CollectArguments
* is combineArguments with (a) new Object[]{...} as a combiner,
* and (b) the combined arguments dropped, in favor of the combined result.
* @param target the method handle to invoke after the argument is prepended
* @param newType the expected type of the new method handle
* @return a new method handle which collects some trailings argument
* @return a new method handle which collects some trailing argument
* into an array, before calling the original method handle
*/
public static
......@@ -900,50 +941,72 @@ public class MethodHandles {
int numCollect = (inargs - collectPos);
if (collectPos < 0 || numCollect < 0)
throw newIllegalArgumentException("wrong number of arguments");
return MethodHandleImpl.collectArguments(IMPL_TOKEN, target, newType, collectPos);
MethodHandle res = MethodHandleImpl.collectArguments(IMPL_TOKEN, target, newType, collectPos, null);
if (res == null) {
throw newIllegalArgumentException("cannot collect from "+newType+" to " +oldType);
}
return res;
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which calls the original method handle,
* after inserting the given argument at the given position.
* The type of the new method handle will drop the corresponding argument
* type from the original handle's type.
* Produce 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 <em>bound parameters</em>, 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.
* <p>
* The given argument object must match the dropped argument type.
* If the dropped argument type is a primitive, the argument object
* must be a wrapper, and is unboxed to produce the primitive.
* 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.
* <p>
* The <i>pos</i> may range between zero and <i>N</i> (inclusively),
* where <i>N</i> is the number of argument types in <i>target</i>,
* meaning to insert the new argument as the first or last (respectively),
* or somewhere in between.
* where <i>N</i> 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 value the argument to insert
* @param values the series of arguments to insert
* @return a new method handle which inserts an additional argument,
* before calling the original method handle
*/
public static
MethodHandle insertArgument(MethodHandle target, int pos, Object value) {
MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
int insCount = values.length;
MethodType oldType = target.type();
ArrayList<Class<?>> ptypes =
new ArrayList<Class<?>>(oldType.parameterList());
int outargs = oldType.parameterCount();
int inargs = outargs - 1;
if (pos < 0 || pos >= outargs)
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");
Class<?> valueType = ptypes.remove(pos);
value = checkValue(valueType, value);
if (pos == 0 && !valueType.isPrimitive()) {
// At least for now, make bound method handles a special case.
// This lets us get by with minimal JVM support, at the expense
// of generating signature-specific adapters as Java bytecodes.
MethodHandle bmh = MethodHandleImpl.bindReceiver(IMPL_TOKEN, target, value);
if (bmh != null) return bmh;
// else fall through to general adapter machinery
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 MethodHandleImpl.bindArgument(IMPL_TOKEN, target, pos, value);
return result;
}
@Deprecated // "use MethodHandles.insertArguments instead"
public static
MethodHandle insertArgument(MethodHandle target, int pos, Object value) {
return insertArguments(target, pos, value);
}
/**
......@@ -953,10 +1016,25 @@ public class MethodHandles {
* The type of the new method handle will insert the given argument
* type(s), at that position, into the original handle's type.
* <p>
* The <i>pos</i> may range between zero and <i>N-1</i>,
* The <i>pos</i> may range between zero and <i>N</i>,
* where <i>N</i> is the number of argument types in <i>target</i>,
* meaning to drop the first or last argument (respectively),
* or an argument somewhere in between.
* <p>
* <b>Example:</b>
* <p><blockquote><pre>
* MethodHandle cat = MethodHandles.lookup().
* findVirtual(String.class, "concat", String.class, String.class);
* System.out.println(cat.&lt;String&gt;invoke("x", "y")); // xy
* MethodHandle d0 = dropArguments(cat, 0, String.class);
* System.out.println(d0.&lt;String&gt;invoke("x", "y", "z")); // xy
* MethodHandle d1 = dropArguments(cat, 1, String.class);
* System.out.println(d1.&lt;String&gt;invoke("x", "y", "z")); // xz
* MethodHandle d2 = dropArguments(cat, 2, String.class);
* System.out.println(d2.&lt;String&gt;invoke("x", "y", "z")); // yz
* MethodHandle d12 = dropArguments(cat, 1, String.class, String.class);
* System.out.println(d12.&lt;String&gt;invoke("w", "x", "y", "z")); // wz
* </pre></blockquote>
* @param target the method handle to invoke after the argument is dropped
* @param valueTypes the type(s) of the argument to drop
* @param pos which argument to drop (zero for the first)
......@@ -964,20 +1042,150 @@ public class MethodHandles {
* before calling the original method handle
*/
public static
MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
if (valueTypes.length == 0) return target;
MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
if (valueTypes.size() == 0) return target;
MethodType oldType = target.type();
int outargs = oldType.parameterCount();
int inargs = outargs + valueTypes.length;
int inargs = outargs + valueTypes.size();
if (pos < 0 || pos >= inargs)
throw newIllegalArgumentException("no argument type to remove");
ArrayList<Class<?>> ptypes =
new ArrayList<Class<?>>(oldType.parameterList());
ptypes.addAll(pos, Arrays.asList(valueTypes));
MethodType newType = MethodType.make(oldType.returnType(), ptypes);
ptypes.addAll(pos, valueTypes);
MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
return MethodHandleImpl.dropArguments(IMPL_TOKEN, target, newType, pos);
}
public static
MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
return dropArguments(target, pos, Arrays.asList(valueTypes));
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* 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.
* <p>
* The pre-processing is performed by one or more method handles,
* specified in the non-null elements of the {@code filters} array.
* (If there are no such elements, the original target is returned.)
* Each filter (that is, each non-null element of {@code filters})
* is applied to the corresponding argument of the adapter.
* <p>
* 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.
* <p>
* It is an error if there are non-null elements of {@code filters}
* which do not correspond to argument positions in the target.
* The actual length of the target array may be any number, it need
* not be the same as the parameter count of the target type.
* (This provides an easy way to filter just the first argument or two
* of a target method handle.)
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
* // there are N arguments in the A sequence
* T target(A[N]...);
* [i&lt;N] V[i] filter[i](B[i]) = filters[i] ?: identity;
* T adapter(B[N]... b) {
* A[N] a...;
* [i&lt;N] a[i] = filter[i](b[i]);
* return target(a...);
* }
* </pre></blockquote>
* @param target the method handle to invoke after arguments are filtered
* @param filters method handles to call initially on filtered arguments
* @return method handle which incorporates the specified argument filtering logic
* @throws IllegalArgumentException if a non-null element of {@code filters}
* does not match a corresponding argument type of {@code target}
*/
public static
MethodHandle filterArguments(MethodHandle target, MethodHandle... filters) {
MethodType targetType = target.type();
MethodHandle adapter = target;
MethodType adapterType = targetType;
int pos = -1, maxPos = targetType.parameterCount();
for (MethodHandle filter : filters) {
pos += 1;
if (filter == null) continue;
if (pos >= maxPos)
throw newIllegalArgumentException("too many filters");
MethodType filterType = filter.type();
if (filterType.parameterCount() != 1
|| filterType.returnType() != targetType.parameterType(pos))
throw newIllegalArgumentException("target and filter types do not match");
adapterType = adapterType.changeParameterType(pos, filterType.parameterType(0));
adapter = MethodHandleImpl.filterArgument(IMPL_TOKEN, adapter, pos, filter);
}
MethodType midType = adapter.type();
if (midType != adapterType)
adapter = MethodHandleImpl.convertArguments(IMPL_TOKEN, adapter, adapterType, midType, null);
return adapter;
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* (Note that {@link #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 #collectArguments} instead, since those
* arguments will not need to be live on the stack on entry to the
* target.)
* <p>
* The first argument of the target must be identical with the
* return value of the combiner.
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
* // 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...);
* }
* </pre></blockquote>
* @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 IllegalArgumentException if the first argument type of
* {@code target} is not the same as {@code combiner}'s return type,
* or if the next {@code foldArgs} 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)
throw misMatchedTypes("target and combiner types", targetType, combinerType);
MethodType newType = targetType.dropParameterTypes(0, 1);
return MethodHandleImpl.foldArguments(IMPL_TOKEN, target, newType, combiner);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Make a method handle which adapts a target method handle,
......@@ -985,18 +1193,18 @@ public class MethodHandles {
* 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.
* of the test must be boolean, and the test is allowed
* to have fewer arguments than the other two method handles.
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
* signature T(A...);
* boolean test(A...);
* T target(A...);
* T fallback(A...);
* T adapter(A... a) {
* T target(A...,B...);
* T fallback(A...,B...);
* T adapter(A... a,B... b) {
* if (test(a...))
* return target(a...);
* return target(a..., b...);
* else
* return fallback(a...);
* return fallback(a..., b...);
* }
* </pre></blockquote>
* @param test method handle used for test, must return boolean
......@@ -1011,10 +1219,23 @@ public class MethodHandles {
MethodHandle guardWithTest(MethodHandle test,
MethodHandle target,
MethodHandle fallback) {
if (target.type() != fallback.type())
throw newIllegalArgumentException("target and fallback types do not match");
if (target.type().changeReturnType(boolean.class) != test.type())
throw newIllegalArgumentException("target and test types do not match");
MethodType gtype = test.type();
MethodType ttype = target.type();
MethodType ftype = fallback.type();
if (ttype != ftype)
throw misMatchedTypes("target and fallback types", ttype, ftype);
MethodType gtype2 = ttype.changeReturnType(boolean.class);
if (gtype2 != gtype) {
if (gtype.returnType() != boolean.class)
throw newIllegalArgumentException("guard type is not a predicate "+gtype);
int gpc = gtype.parameterCount(), tpc = ttype.parameterCount();
if (gpc < tpc) {
test = dropArguments(test, gpc, ttype.parameterList().subList(gpc, tpc));
gtype = test.type();
}
if (gtype2 != gtype)
throw misMatchedTypes("target and test types", ttype, gtype);
}
/* {
MethodHandle invoke = findVirtual(MethodHandle.class, "invoke", target.type());
static MethodHandle choose(boolean z, MethodHandle t, MethodHandle f) {
......@@ -1027,7 +1248,7 @@ public class MethodHandles {
}
// choose = \z.(z ? target : fallback)
MethodHandle choose = findVirtual(MethodHandles.class, "choose",
MethodType.make(boolean.class, MethodHandle.class, MethodHandle.class));
MethodType.methodType(boolean.class, MethodHandle.class, MethodHandle.class));
choose = appendArgument(choose, target);
choose = appendArgument(choose, fallback);
MethodHandle dispatch = compose(choose, test);
......@@ -1038,67 +1259,88 @@ public class MethodHandles {
return MethodHandleImpl.makeGuardWithTest(IMPL_TOKEN, test, target, fallback);
}
static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Adapt a target method handle {@code target} by first processing
* its arguments, and then calling the target.
* The initial processing is performed by a second method handle, the {@code combiner}.
* After this, control passes to the {@code target}, with the same arguments.
* <p>
* The return value of the {@code combiner} is inserted into the argument list
* for the {@code target} at the indicated position {@code pos}, if it is non-negative.
* Except for this inserted argument (if any), the argument types of
* the target {@code target} and the {@code combiner} must be identical.
* <p>
* (Note that {@link #dropArguments} can be used to remove any arguments
* that either the {@code combiner} or {@code target} does not wish to receive.)
* 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.
* <p>
* The combiner handle must have the same argument types as the
* target handle, but must return {@link MethodHandle} instead of
* the ultimate return type. The returned method handle, in turn,
* is required to have exactly the given final method type.
* The handler must have leading parameter of {@code exType} or a supertype,
* followed by arguments which correspond <em>(how? TBD)</em> to
* all the parameters of the target.
* The target and handler must return the same type.
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
* signature V(A[pos]..., B...);
* signature T(A[pos]..., V, B...);
* T target(A... a, V v, B... b);
* V combiner(A..., B...);
* T adapter(A... a, B... b) {
* V v = combiner(a..., b...);
* return target(a..., v, b...);
* T target(A...);
* T handler(ExType, A...);
* T adapter(A... a) {
* try {
* return target(a...);
* } catch (ExType ex) {
* return handler(ex, a...);
* }
* }
* </pre></blockquote>
* @param target the method handle to invoke after arguments are combined
* @param pos where the return value of {@code combiner} is to
* be inserted as an argument to {@code target}
* @param combiner method handle to call initially on the incoming arguments
* @return method handle which incorporates the specified dispatch logic
* @throws IllegalArgumentException if {@code combiner} does not itself
* return either void or the {@code pos}-th argument of {@code target},
* or does not have the same argument types as {@code target}
* (minus the inserted argument)
* @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 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 combineArguments(MethodHandle target, int pos, MethodHandle combiner) {
MethodType mhType = target.type();
Class<?> combineType = combiner.type().returnType();
MethodType incomingArgs;
if (pos < 0) {
// No inserted argument; target & combiner must have same argument types.
incomingArgs = mhType;
if (!incomingArgs.changeReturnType(combineType).equals(combiner.type()))
throw newIllegalArgumentException("target and combiner types do not match");
} else {
// Inserted argument.
if (pos >= mhType.parameterCount()
|| mhType.parameterType(pos) != combineType)
throw newIllegalArgumentException("inserted combiner argument does not match target");
incomingArgs = mhType.dropParameterType(pos);
}
if (!incomingArgs.changeReturnType(combineType).equals(combiner.type())) {
throw newIllegalArgumentException("target and combiner types do not match");
}
return MethodHandleImpl.combineArguments(IMPL_TOKEN, target, combiner, pos);
MethodHandle catchException(MethodHandle target,
Class<? extends Throwable> exType,
MethodHandle handler) {
MethodType targetType = target.type();
MethodType handlerType = handler.type();
boolean ok = (targetType.parameterCount() ==
handlerType.parameterCount() - 1);
// for (int i = 0; ok && i < numExArgs; i++) {
// if (targetType.parameterType(i) != handlerType.parameterType(1+i))
// ok = false;
// }
if (!ok)
throw newIllegalArgumentException("target and handler types do not match");
return MethodHandleImpl.makeGuardWithCatch(IMPL_TOKEN, target, exType, handler);
}
/**
* Produce 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.
*/
public static
MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
return MethodHandleImpl.throwException(IMPL_TOKEN, MethodType.methodType(returnType, exType));
}
/** Alias for {@link MethodType#methodType}. */
@Deprecated // "use MethodType.methodType instead"
public static MethodType methodType(Class<?> rtype) {
return MethodType.methodType(rtype);
}
/** Alias for {@link MethodType#methodType}. */
@Deprecated // "use MethodType.methodType instead"
public static MethodType methodType(Class<?> rtype, Class<?> ptype) {
return MethodType.methodType(rtype, ptype);
}
/** Alias for {@link MethodType#methodType}. */
@Deprecated // "use MethodType.methodType instead"
public static MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
return MethodType.methodType(rtype, ptype0, ptypes);
}
}
......@@ -32,7 +32,7 @@ import java.util.List;
import sun.dyn.Access;
import sun.dyn.Invokers;
import sun.dyn.MethodTypeImpl;
import sun.dyn.util.BytecodeSignature;
import sun.dyn.util.BytecodeDescriptor;
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
......@@ -63,7 +63,7 @@ class MethodType {
static {
// This hack allows the implementation package special access to
// the internals of MethodType. In particular, the Form has all sorts
// 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; }
......@@ -114,51 +114,76 @@ class MethodType {
* @throws IllegalArgumentException if any of the ptypes is void
*/
public static
MethodType make(Class<?> rtype, Class<?>[] ptypes) {
MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
return makeImpl(rtype, ptypes, false);
}
@Deprecated public static
MethodType make(Class<?> rtype, Class<?>[] ptypes) {
return methodType(rtype, ptypes);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}. */
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}. */
public static
MethodType methodType(Class<?> rtype, List<? extends Class<?>> ptypes) {
boolean notrust = false; // random List impl. could return evil ptypes array
return makeImpl(rtype, ptypes.toArray(NO_PTYPES), notrust);
}
@Deprecated public static
MethodType make(Class<?> rtype, List<? extends Class<?>> ptypes) {
return makeImpl(rtype, ptypes.toArray(NO_PTYPES), true);
return methodType(rtype, ptypes);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* The leading parameter type is prepended to the remaining array.
*/
public static
MethodType make(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
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);
}
@Deprecated public static
MethodType make(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
return methodType(rtype, ptype0, ptypes);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* The resulting method has no parameter types.
*/
public static
MethodType make(Class<?> rtype) {
MethodType methodType(Class<?> rtype) {
return makeImpl(rtype, NO_PTYPES, true);
}
@Deprecated public static
MethodType make(Class<?> rtype) {
return methodType(rtype);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* The resulting method has the single given parameter type.
*/
public static
MethodType make(Class<?> rtype, Class<?> ptype0) {
MethodType methodType(Class<?> rtype, Class<?> ptype0) {
return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
}
@Deprecated public static
MethodType make(Class<?> rtype, Class<?> ptype0) {
return methodType(rtype, ptype0);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* The resulting method has the same parameter types as {@code ptypes},
* and the specified return type.
*/
public static
MethodType make(Class<?> rtype, MethodType ptypes) {
MethodType methodType(Class<?> rtype, MethodType ptypes) {
return makeImpl(rtype, ptypes.ptypes, true);
}
@Deprecated public static
MethodType make(Class<?> rtype, MethodType ptypes) {
return methodType(rtype, ptypes);
}
/**
* Sole factory method to find or create an interned method type.
......@@ -202,15 +227,16 @@ class MethodType {
private static final MethodType[] objectOnlyTypes = new MethodType[20];
/**
* Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
* All parameters and the return type will be Object, except the final varargs parameter if any.
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* 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 Object[]
* @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
* @see #makeGeneric(int)
* @see #genericMethodType(int)
*/
public static
MethodType makeGeneric(int objectArgCount, boolean varargs) {
MethodType genericMethodType(int objectArgCount, boolean varargs) {
MethodType mt;
int ivarargs = (!varargs ? 0 : 1);
int ootIndex = objectArgCount*2 + ivarargs;
......@@ -227,19 +253,27 @@ class MethodType {
}
return mt;
}
@Deprecated public static
MethodType makeGeneric(int objectArgCount, boolean varargs) {
return genericMethodType(objectArgCount, varargs);
}
/**
* 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
* @see #makeGeneric(int, boolean)
* @see #genericMethodType(int, boolean)
*/
public static
MethodType genericMethodType(int objectArgCount) {
return genericMethodType(objectArgCount, false);
}
@Deprecated public static
MethodType makeGeneric(int objectArgCount) {
return makeGeneric(objectArgCount, false);
return genericMethodType(objectArgCount);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @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
......@@ -251,11 +285,10 @@ class MethodType {
return makeImpl(rtype, nptypes, true);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
* @param num the position (zero-based) of the inserted parameter type
* @param nptype a new parameter type to insert into the parameter list
* @return the same type, except with the selected parameter inserted
/** Convenience method for {@link #insertParameterTypes}.
* @deprecated Use {@link #insertParameterTypes} instead.
*/
@Deprecated
public MethodType insertParameterType(int num, Class<?> nptype) {
int len = ptypes.length;
Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+1);
......@@ -264,23 +297,73 @@ class MethodType {
return makeImpl(rtype, nptypes, true);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
* @param num the index (zero-based) of the parameter type to remove
* @return the same type, except with the selected parameter removed
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param num the position (zero-based) of the inserted parameter type(s)
* @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
* @return the same type, except with the selected parameter(s) inserted
*/
public MethodType dropParameterType(int num) {
public MethodType insertParameterTypes(int num, Class<?>... ptypesToInsert) {
int len = ptypes.length;
if (num < 0 || num > len)
throw newIllegalArgumentException("num="+num); //SPECME
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);
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param num the position (zero-based) of the inserted parameter type(s)
* @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
* @return the same type, except with the selected parameter(s) inserted
*/
public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) {
return insertParameterTypes(num, ptypesToInsert.toArray(NO_PTYPES));
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @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
*/
public MethodType dropParameterTypes(int start, int end) {
int len = ptypes.length;
if (!(0 <= start && start <= end && end <= len))
throw newIllegalArgumentException("start="+start+" end="+end); //SPECME
if (start == end) return this;
Class<?>[] nptypes;
if (num == 0) {
nptypes = Arrays.copyOfRange(ptypes, 1, len);
if (start == 0) {
if (end == len) {
// drop all parameters
nptypes = NO_PTYPES;
} else {
// drop initial parameter(s)
nptypes = Arrays.copyOfRange(ptypes, end, len);
}
} else {
nptypes = Arrays.copyOfRange(ptypes, 0, len-1);
System.arraycopy(ptypes, num+1, nptypes, num, (len-1)-num);
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);
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
/** Convenience method for {@link #dropParameterTypes}.
* @deprecated Use {@link #dropParameterTypes} instead.
*/
@Deprecated
public MethodType dropParameterType(int num) {
return dropParameterTypes(num, num+1);
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param nrtype a return parameter type to replace the old one with
* @return the same type, except with the return type change
*/
......@@ -291,6 +374,7 @@ class MethodType {
/** Convenience method.
* Report 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() {
......@@ -300,39 +384,47 @@ class MethodType {
/** Convenience method.
* Report 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;
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
* Erase all reference types to Object.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Erase all reference types to {@code Object}.
* 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();
}
/** Convenience method for {@link #makeGeneric(int)}.
* Convert all types, both reference and primitive, to Object.
/** Convenience method for {@link #genericMethodType(int)}.
* Convert all types, both reference and primitive, to {@code Object}.
* 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 makeGeneric(parameterCount());
return genericMethodType(parameterCount());
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Convert all primitive types to their corresponding wrapper types.
* 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;
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Convert all wrapper types to their corresponding primitive types.
* 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
*/
......@@ -391,6 +483,7 @@ class MethodType {
/**
* Convenience method to present the arguments as an array.
* 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() {
......@@ -491,7 +584,7 @@ class MethodType {
return form.parameterSlotCount();
}
/** Number of JVM stack slots which carry all parameters after
/** 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
......@@ -532,7 +625,7 @@ class MethodType {
return form.returnSlotCount();
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Find or create an instance (interned) of the given method type.
* Any class or interface name embedded in the signature string
* will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
......@@ -544,16 +637,16 @@ class MethodType {
* <p>
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
* @param bytecodeSignature a bytecode-level signature string "(T...)T"
* @param descriptor a bytecode-level signature string "(T...)T"
* @param loader the class loader in which to look up the types
* @return a method type matching the bytecode-level signature
* @throws IllegalArgumentException if the string is not well-formed
* @throws TypeNotPresentException if a named type cannot be found
*/
public static MethodType fromBytecodeString(String bytecodeSignature, ClassLoader loader)
public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
throws IllegalArgumentException, TypeNotPresentException
{
List<Class<?>> types = BytecodeSignature.parseMethod(bytecodeSignature, loader);
List<Class<?>> types = BytecodeDescriptor.parseMethod(descriptor, loader);
Class<?> rtype = types.remove(types.size() - 1);
Class<?>[] ptypes = types.toArray(NO_PTYPES);
return makeImpl(rtype, ptypes, true);
......@@ -565,11 +658,21 @@ class MethodType {
* <p>
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
* {@link #fromBytecodeString(java.lang.String, java.lang.ClassLoader)},
* {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader)},
* because the latter requires a suitable class loader argument.
* @return the bytecode signature representation
*/
public String toMethodDescriptorString() {
return BytecodeDescriptor.unparse(this);
}
/** Temporary alias for toMethodDescriptorString; delete after M3. */
public String toBytecodeString() {
return BytecodeSignature.unparse(this);
return toMethodDescriptorString();
}
/** Temporary alias for fromMethodDescriptorString; delete after M3. */
public static MethodType fromBytecodeString(String descriptor, ClassLoader loader)
throws IllegalArgumentException, TypeNotPresentException {
return fromMethodDescriptorString(descriptor, loader);
}
}
......@@ -24,6 +24,7 @@
*/
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* This package contains dynamic language support provided directly by
* the Java core class libraries and virtual machine.
* @author John Rose, JSR 292 EG
......
......@@ -30,7 +30,7 @@ import sun.dyn.util.Wrapper;
import java.dyn.*;
import java.util.Arrays;
import static sun.dyn.MethodHandleNatives.Constants.*;
import static sun.dyn.MethodHandleImpl.newIllegalArgumentException;
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* This method handle performs simple conversion or checking of a single argument.
......@@ -302,7 +302,22 @@ public class AdapterMethodHandle extends BoundMethodHandle {
*/
private static int type2size(int type) {
assert(type >= T_BOOLEAN && type <= T_OBJECT);
return (type == T_FLOAT || type == T_DOUBLE) ? 2 : 1;
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. */
......@@ -310,16 +325,16 @@ public class AdapterMethodHandle extends BoundMethodHandle {
assert(src == (src & 0xF));
assert(dest == (dest & 0xF));
assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF);
long stackMove = type2size(dest) - type2size(src);
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 |
stackMove << CONV_STACK_MOVE_SHIFT
insertStackMove(stackMove)
);
}
private static long makeConv(int convOp, int argnum, int stackMove) {
assert(convOp >= OP_SWAP_ARGS && convOp <= OP_SPREAD_ARGS);
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;
......@@ -327,12 +342,21 @@ public class AdapterMethodHandle extends BoundMethodHandle {
(long) convOp << CONV_OP_SHIFT |
(int) src << CONV_SRC_TYPE_SHIFT |
(int) dest << CONV_DEST_TYPE_SHIFT |
stackMove << CONV_STACK_MOVE_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);
return (long) convOp << CONV_OP_SHIFT; // stackMove, src, dst, argnum all zero
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;
......@@ -348,16 +372,6 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** One of OP_RETYPE_ONLY, etc. */
int conversionOp() { return (conversion & CONV_OP_MASK) >> CONV_OP_SHIFT; }
@Override
public String toString() {
return addTypeString(this, "Adapted[" + basicToString(nonAdapter((MethodHandle)vmtarget)) + "]");
}
private static MethodHandle nonAdapter(MethodHandle mh) {
return (MethodHandle)
MethodHandleNatives.getTarget(mh, ETF_DIRECT_HANDLE);
}
/* 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.
......@@ -399,14 +413,14 @@ public class AdapterMethodHandle extends BoundMethodHandle {
//if (false) return 1; // never adaptable!
return -1; // some significant difference
}
private static int diffParamTypes(MethodType adapterType, int tstart,
MethodType targetType, int astart,
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(tstart+i);
Class<?> dest = targetType.parameterType(astart+i);
Class<?> src = adapterType.parameterType(astart+i);
Class<?> dest = targetType.parameterType(tstart+i);
if ((!raw
? VerifyType.canPassUnchecked(src, dest)
: VerifyType.canPassRaw(src, dest)
......@@ -422,7 +436,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Can a retyping adapter (alone) validly convert the target to newType? */
public static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
return canRetypeOnly(newType, targetType, false);
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
......@@ -430,14 +444,14 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* reference conversions on return. This last feature requires that the
* caller be trusted, and perform explicit cast conversions on return values.
*/
static boolean canRawRetypeOnly(MethodType newType, MethodType targetType) {
return canRetypeOnly(newType, targetType, true);
public static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
return canRetype(newType, targetType, true);
}
static boolean canRetypeOnly(MethodType newType, MethodType targetType, boolean raw) {
if (!convOpSupported(OP_RETYPE_ONLY)) return false;
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((diff == 0) == VerifyType.isNullConversion(newType, targetType));
assert(raw || (diff == 0) == VerifyType.isNullConversion(newType, targetType));
return diff == 0;
}
......@@ -447,19 +461,21 @@ public class AdapterMethodHandle extends BoundMethodHandle {
*/
public static MethodHandle makeRetypeOnly(Access token,
MethodType newType, MethodHandle target) {
return makeRetypeOnly(token, newType, target, false);
return makeRetype(token, newType, target, false);
}
public static MethodHandle makeRawRetypeOnly(Access token,
public static MethodHandle makeRetypeRaw(Access token,
MethodType newType, MethodHandle target) {
return makeRetypeOnly(token, newType, target, true);
return makeRetype(token, newType, target, true);
}
static MethodHandle makeRetypeOnly(Access token,
static MethodHandle makeRetype(Access token,
MethodType newType, MethodHandle target, boolean raw) {
Access.check(token);
if (!canRetypeOnly(newType, target.type(), 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(OP_RETYPE_ONLY));
return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
}
/** Can a checkcast adapter validly convert the target to newType?
......@@ -492,7 +508,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
Access.check(token);
if (!canCheckCast(newType, target.type(), arg, castType))
return null;
long conv = makeConv(OP_CHECK_CAST, arg, 0);
long conv = makeConv(OP_CHECK_CAST, arg, T_OBJECT, T_OBJECT);
return new AdapterMethodHandle(target, newType, conv, castType);
}
......@@ -537,10 +553,9 @@ public class AdapterMethodHandle extends BoundMethodHandle {
int arg, Class<?> convType) {
Access.check(token);
MethodType oldType = target.type();
Class<?> src = newType.parameterType(arg);
Class<?> dst = oldType.parameterType(arg);
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);
}
......@@ -607,8 +622,6 @@ public class AdapterMethodHandle extends BoundMethodHandle {
return null;
}
// TO DO: makeSwapArguments, makeRotateArguments, makeDuplicateArguments
/** Can an adapter simply drop arguments to convert the target to newType? */
public static boolean canDropArguments(MethodType newType, MethodType targetType,
int dropArgPos, int dropArgCount) {
......@@ -643,26 +656,195 @@ public class AdapterMethodHandle extends BoundMethodHandle {
Access.check(token);
if (dropArgCount == 0)
return makeRetypeOnly(IMPL_TOKEN, newType, target);
MethodType mt = target.type();
int argCount = mt.parameterCount();
if (!canDropArguments(newType, mt, dropArgPos, dropArgCount))
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;
int dropSlotCount, dropSlotPos;
if (dropArgCount >= argCount) {
assert(dropArgPos == argCount-1);
dropSlotPos = 0;
dropSlotCount = mt.parameterSlotCount();
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 {
// arglist: [0: keep... | dpos: drop... | dpos+dcount: keep... ]
int lastDroppedArg = dropArgPos + dropArgCount - 1;
int lastKeptArg = dropArgPos - 1; // might be -1, which is OK
dropSlotPos = mt.parameterSlotDepth(1+lastDroppedArg);
int lastKeptSlot = mt.parameterSlotDepth(1+lastKeptArg);
dropSlotCount = lastKeptSlot - dropSlotPos;
assert(dropSlotCount >= dropArgCount);
return (-1-((-1-rotateBy) % argCount)) + argCount;
}
long conv = makeConv(OP_DROP_ARGS, dropArgPos, +dropSlotCount);
return new AdapterMethodHandle(target, newType, dropSlotCount, conv);
}
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? */
......@@ -676,10 +858,10 @@ public class AdapterMethodHandle extends BoundMethodHandle {
if (spreadArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, spreadArgPos, false) != 0)
return false;
int afterPos = spreadArgPos + spreadArgCount;
int afterCount = nptypes - afterPos;
int afterCount = nptypes - (spreadArgPos + 1);
if (spreadArgPos < 0 || spreadArgPos >= nptypes ||
spreadArgCount < 0 ||
targetType.parameterCount() != nptypes - 1 + spreadArgCount)
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)
......@@ -697,32 +879,40 @@ public class AdapterMethodHandle extends BoundMethodHandle {
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 mt = target.type();
int argCount = mt.parameterCount();
if (!canSpreadArguments(newType, mt, spreadArgType, spreadArgPos, spreadArgCount))
MethodType targetType = target.type();
if (!canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount))
return null;
int spreadSlotCount, spreadSlotPos;
if (spreadArgCount >= argCount) {
assert(spreadArgPos == argCount-1);
spreadSlotPos = 0;
spreadSlotCount = mt.parameterSlotCount();
} else {
// arglist: [0: keep... | dpos: spread... | dpos+dcount: keep... ]
int lastSpreadArg = spreadArgPos + spreadArgCount - 1;
int lastKeptArg = spreadArgPos - 1; // might be -1, which is OK
spreadSlotPos = mt.parameterSlotDepth(1+lastSpreadArg);
int lastKeptSlot = mt.parameterSlotDepth(1+lastKeptArg);
spreadSlotCount = lastKeptSlot - spreadSlotPos;
assert(spreadSlotCount >= spreadArgCount);
}
long conv = makeConv(OP_SPREAD_ARGS, spreadArgPos, spreadSlotCount);
return new AdapterMethodHandle(target, newType, conv, spreadArgType);
// 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 nonAdapter((MethodHandle)vmtarget).toString();
}
private static MethodHandle nonAdapter(MethodHandle mh) {
while (mh instanceof AdapterMethodHandle) {
mh = (MethodHandle) mh.vmtarget;
}
return mh;
}
}
......@@ -28,6 +28,10 @@ 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
......@@ -35,18 +39,23 @@ import java.dyn.*;
* when the handle is created, not when it is invoked.
* @author jrose
*/
public class BoundMethodHandle extends MethodHandle {
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.
// Exception: JavaMethodHandle constructors are protected.
// (The link between JMH and BMH is temporary.)
/** 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().dropParameterType(0));
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();
......@@ -56,32 +65,34 @@ public class BoundMethodHandle extends MethodHandle {
} else {
this.vmtarget = mh;
}
}
private static final int REF_ARG = 0, PRIM_ARG = 1, SELF_ARG = 2;
}
/** 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, argument, argnum, mh.type().parameterType(argnum).isPrimitive() ? PRIM_ARG : REF_ARG);
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(MethodHandle mh, Object argument, int argnum, int whichArg) {
super(Access.TOKEN, mh.type().dropParameterType(argnum));
if (whichArg == PRIM_ARG)
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 {
if (whichArg == SELF_ARG) argument = this;
this.argument = checkReferenceArgument(argument, mh, argnum);
}
this.vmargslot = this.type().parameterSlotDepth(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
this.vmtarget = null; // maybe updated by JVM
MethodHandleNatives.init(this, mh, argnum);
} else {
this.vmtarget = mh;
......@@ -97,29 +108,65 @@ public class BoundMethodHandle extends MethodHandle {
assert(this.getClass() == AdapterMethodHandle.class);
}
/** Initialize the current object as a method handle, binding it
* as the {@code argnum}th argument of the method handle {@code entryPoint}.
/** Initialize the current object as a Java 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 {@code argnum}th argument
* same as {@code entryPoint}, except that the first argument
* type will be dropped.
*/
public BoundMethodHandle(MethodHandle entryPoint, int argnum) {
this(entryPoint, null, argnum, SELF_ARG);
// Note: If the conversion fails, perhaps because of a bad entryPoint,
// the MethodHandle.type field will not be filled in, and therefore
// no MH.invoke call will ever succeed. The caller may retain a pointer
// to the broken method handle, but no harm can be done with it.
protected BoundMethodHandle(MethodHandle entryPoint) {
super(Access.TOKEN, entryPoint.type().dropParameterTypes(0, 1));
this.argument = this; // kludge; get rid of
this.vmargslot = this.type().parameterSlotDepth(0);
initTarget(entryPoint, 0);
assert(this instanceof JavaMethodHandle);
}
/** Initialize the current object as a 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.
/** Initialize the current object as a Java method handle.
*/
public BoundMethodHandle(MethodHandle entryPoint) {
this(entryPoint, null, 0, SELF_ARG);
protected BoundMethodHandle(String entryPointName, MethodType type, boolean matchArity) {
super(Access.TOKEN, null);
MethodHandle entryPoint
= findJavaMethodHandleEntryPoint(this.getClass(),
entryPointName, type, matchArity);
MethodHandleImpl.initType(this, entryPoint.type().dropParameterTypes(0, 1));
this.argument = this; // kludge; get rid of
this.vmargslot = this.type().parameterSlotDepth(0);
initTarget(entryPoint, 0);
assert(this instanceof JavaMethodHandle);
}
private static
MethodHandle findJavaMethodHandleEntryPoint(Class<?> caller,
String name,
MethodType type,
boolean matchArity) {
if (matchArity) type.getClass(); // elicit NPE
List<MemberName> methods = IMPL_NAMES.getMethods(caller, true, name, null, caller);
MethodType foundType = null;
MemberName foundMethod = null;
for (MemberName method : methods) {
MethodType mtype = method.getMethodType();
if (type != null && type.parameterCount() != mtype.parameterCount())
continue;
else if (foundType == null)
foundType = mtype;
else if (foundType != mtype)
throw newIllegalArgumentException("more than one method named "+name+" in "+caller.getName());
// discard overrides
if (foundMethod == null)
foundMethod = method;
else if (foundMethod.getDeclaringClass().isAssignableFrom(method.getDeclaringClass()))
foundMethod = method;
}
if (foundMethod == null)
throw newIllegalArgumentException("no method named "+name+" in "+caller.getName());
MethodHandle entryPoint = MethodHandleImpl.findMethod(IMPL_TOKEN, foundMethod, true, caller);
if (type != null) {
MethodType epType = type.insertParameterTypes(0, entryPoint.type().parameterType(0));
entryPoint = MethodHandles.convertArguments(entryPoint, epType);
}
return entryPoint;
}
/** Make sure the given {@code argument} can be used as {@code argnum}-th
......@@ -175,6 +222,24 @@ public class BoundMethodHandle extends MethodHandle {
@Override
public String toString() {
return "Bound[" + super.toString() + "]";
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 super.toString(); // <unknown>, probably
}
assert(mh != this);
if (mh instanceof JavaMethodHandle)
break; // access JMH.toString(), not BMH.toString()
}
return mh.toString();
}
}
......@@ -26,34 +26,51 @@
package sun.dyn;
import java.dyn.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* The CallSite privately created by the JVM at every invokedynamic instruction.
* Parts of CallSite known to the JVM.
* FIXME: Merge all this into CallSite proper.
* @author jrose
*/
class CallSiteImpl extends CallSite {
// Fields used only by the JVM. Do not use or change.
public class CallSiteImpl {
// Field used only by the JVM. Do not use or change.
private Object vmmethod;
// Values supplied by the JVM:
int callerMID, callerBCI;
protected int callerMID, callerBCI;
private CallSiteImpl(Class<?> caller, String name, MethodType type) {
super(caller, name, type);
private MethodHandle target;
protected final Object caller; // usually a class
protected final String name;
protected final MethodType type;
/** called only directly from CallSite() */
protected CallSiteImpl(Access token, Object caller, String name, MethodType type) {
Access.check(token);
this.caller = caller;
this.name = name;
this.type = type;
}
/** native version of setTarget */
protected void setTarget(MethodHandle mh) {
//System.out.println("setTarget "+this+" := "+mh);
// XXX I don't know how to fix this properly.
// if (false && MethodHandleNatives.JVM_SUPPORT) // FIXME: enable this
// MethodHandleNatives.linkCallSite(this, mh);
// else
this.target = mh;
}
@Override
public void setTarget(MethodHandle mh) {
checkTarget(mh);
if (MethodHandleNatives.JVM_SUPPORT)
MethodHandleNatives.linkCallSite(this, (MethodHandle) mh);
else
super.setTarget(mh);
protected MethodHandle getTarget() {
return target;
}
private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE =
MethodHandleImpl.IMPL_LOOKUP.findStatic(CallSite.class, "privateInitializeCallSite",
MethodType.make(void.class, CallSite.class, int.class, int.class));
MethodType.methodType(void.class, CallSite.class, int.class, int.class));
// this is the up-call from the JVM:
static CallSite makeSite(Class<?> caller, String name, MethodType type,
......@@ -61,10 +78,25 @@ class CallSiteImpl extends CallSite {
MethodHandle bsm = Linkage.getBootstrapMethod(caller);
if (bsm == null)
throw new InvokeDynamicBootstrapError("class has no bootstrap method: "+caller);
CallSite site = bsm.<CallSite>invoke(caller, name, type);
CallSite site;
try {
site = bsm.<CallSite>invoke(caller, name, type);
} catch (Throwable ex) {
throw new InvokeDynamicBootstrapError("exception thrown while linking", ex);
}
if (site == null)
throw new InvokeDynamicBootstrapError("class bootstrap method failed to create a call site: "+caller);
PRIVATE_INITIALIZE_CALL_SITE.<void>invoke(site, callerMID, callerBCI);
if (site.type() != type)
throw new InvokeDynamicBootstrapError("call site type not initialized correctly: "+site);
if (site.callerClass() != caller)
throw new InvokeDynamicBootstrapError("call site caller not initialized correctly: "+site);
if ((Object)site.name() != name)
throw new InvokeDynamicBootstrapError("call site name not initialized correctly: "+site);
try {
PRIVATE_INITIALIZE_CALL_SITE.<void>invoke(site, callerMID, callerBCI);
} catch (Throwable ex) {
throw new InvokeDynamicBootstrapError("call site initialization exception", ex);
}
return site;
}
}
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -27,7 +27,6 @@ package sun.dyn;
import java.dyn.JavaMethodHandle;
import java.dyn.MethodHandle;
import java.dyn.MethodHandles;
import java.dyn.MethodType;
/**
......@@ -42,16 +41,21 @@ public class FilterOneArgument extends JavaMethodHandle {
protected final MethodHandle filter; // Object -> Object
protected final MethodHandle target; // Object -> Object
protected Object entryPoint(Object argument) {
Object filteredArgument = filter.<Object>invoke(argument);
return target.<Object>invoke(filteredArgument);
@Override
public String toString() {
return target.toString();
}
protected Object invoke(Object argument) throws Throwable {
Object filteredArgument = filter.invoke(argument);
return target.invoke(filteredArgument);
}
private static final MethodHandle entryPoint =
MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "entryPoint", MethodType.makeGeneric(1));
private static final MethodHandle INVOKE =
MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke", MethodType.genericMethodType(1));
protected FilterOneArgument(MethodHandle filter, MethodHandle target) {
super(entryPoint);
super(INVOKE);
this.filter = filter;
this.target = target;
}
......@@ -62,10 +66,6 @@ public class FilterOneArgument extends JavaMethodHandle {
return new FilterOneArgument(filter, target);
}
public String toString() {
return filter + "|>" + target;
}
// MethodHandle make(MethodHandle filter1, MethodHandle filter2, MethodHandle target) {
// MethodHandle filter = make(filter1, filter2);
// return make(filter, target);
......
......@@ -36,8 +36,8 @@ import sun.dyn.util.ValueConversions;
import sun.dyn.util.Wrapper;
/**
* Adapters which mediate between incoming calls which are not generic
* and outgoing calls which are. Any call can be represented generically
* 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.
* <p>
* A call is "generic" (in MethodHandle terms) if its MethodType features
......@@ -50,9 +50,6 @@ import sun.dyn.util.Wrapper;
* 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.)
* <p>
* This adapter can sometimes be more directly implemented
* by the JVM's built-in OP_SPREAD_ARGS adapter.
* @author jrose
*/
class FromGeneric {
......@@ -99,7 +96,7 @@ class FromGeneric {
}
this.internalType = internalType0;
this.adapter = ad;
MethodType tepType = targetType.insertParameterType(0, adapter.getClass());
MethodType tepType = targetType.insertParameterTypes(0, adapter.getClass());
this.entryPoint = ad.prototypeEntryPoint();
this.returnConversion = computeReturnConversion(targetType, internalType0);
this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
......@@ -146,7 +143,7 @@ class FromGeneric {
if (fixArgs == null)
throw new InternalError("bad fixArgs");
// reinterpret the calling sequence as raw:
MethodHandle retyper = AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN,
MethodHandle retyper = AdapterMethodHandle.makeRetypeRaw(Access.TOKEN,
Invokers.invokerType(internalType), fixArgs);
if (retyper == null)
throw new InternalError("bad retyper");
......@@ -226,7 +223,10 @@ class FromGeneric {
// Produce an instance configured as a prototype.
return ctor.newInstance(entryPoint);
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException 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) {
}
......@@ -260,6 +260,11 @@ class FromGeneric {
protected final MethodHandle convert; // raw(R) => Object
protected final MethodHandle target; // (any**N) => R
@Override
public String toString() {
return target.toString();
}
protected boolean isPrototype() { return target == null; }
protected Adapter(MethodHandle entryPoint) {
this(entryPoint, null, entryPoint, null);
......@@ -284,11 +289,11 @@ class FromGeneric {
// { return new ThisType(entryPoint, convert, target); }
/// Conversions on the value returned from the target.
protected Object convert_L(Object result) { return convert.<Object>invoke(result); }
protected Object convert_I(int result) { return convert.<Object>invoke(result); }
protected Object convert_J(long result) { return convert.<Object>invoke(result); }
protected Object convert_F(float result) { return convert.<Object>invoke(result); }
protected Object convert_D(double result) { return convert.<Object>invoke(result); }
protected Object convert_L(Object result) throws Throwable { return convert.<Object>invoke(result); }
protected Object convert_I(int result) throws Throwable { return convert.<Object>invoke(result); }
protected Object convert_J(long result) throws Throwable { return convert.<Object>invoke(result); }
protected Object convert_F(float result) throws Throwable { return convert.<Object>invoke(result); }
protected Object convert_D(double result) throws Throwable { return convert.<Object>invoke(result); }
static private final String CLASS_PREFIX; // "sun.dyn.FromGeneric$"
static {
......@@ -317,11 +322,11 @@ class FromGeneric {
{ 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) { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
protected Object invoke_I2(Object a0, Object a1) { return convert_I(invoker.<int >invoke(target, a0, a1)); }
protected Object invoke_J2(Object a0, Object a1) { return convert_J(invoker.<long >invoke(target, a0, a1)); }
protected Object invoke_F2(Object a0, Object a1) { return convert_F(invoker.<float >invoke(target, a0, a1)); }
protected Object invoke_D2(Object a0, Object a1) { return convert_D(invoker.<double>invoke(target, a0, a1)); }
protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1)); }
protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1)); }
protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1)); }
protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1)); }
}
// */
......@@ -342,7 +347,7 @@ class genclasses {
" 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@) { return convert_@Rc@(invoker.<@R@>invoke(target@av@)); }",
" protected Object invoke_@catN@(@Tvav@) throws Throwable { return convert_@Rc@(invoker.<@R@>invoke(target@av@)); }",
" //@end-R@",
" }",
} };
......@@ -498,11 +503,11 @@ class genclasses {
{ 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() { return convert_L(invoker.<Object>invoke(target)); }
protected Object invoke_I0() { return convert_I(invoker.<int >invoke(target)); }
protected Object invoke_J0() { return convert_J(invoker.<long >invoke(target)); }
protected Object invoke_F0() { return convert_F(invoker.<float >invoke(target)); }
protected Object invoke_D0() { return convert_D(invoker.<double>invoke(target)); }
protected Object invoke_L0() throws Throwable { return convert_L(invoker.<Object>invoke(target)); }
protected Object invoke_I0() throws Throwable { return convert_I(invoker.<int >invoke(target)); }
protected Object invoke_J0() throws Throwable { return convert_J(invoker.<long >invoke(target)); }
protected Object invoke_F0() throws Throwable { return convert_F(invoker.<float >invoke(target)); }
protected Object invoke_D0() throws Throwable { return convert_D(invoker.<double>invoke(target)); }
}
static class A1 extends Adapter {
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -510,11 +515,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(target, a0)); }
protected Object invoke_I1(Object a0) { return convert_I(invoker.<int >invoke(target, a0)); }
protected Object invoke_J1(Object a0) { return convert_J(invoker.<long >invoke(target, a0)); }
protected Object invoke_F1(Object a0) { return convert_F(invoker.<float >invoke(target, a0)); }
protected Object invoke_D1(Object a0) { return convert_D(invoker.<double>invoke(target, a0)); }
protected Object invoke_L1(Object a0) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0)); }
protected Object invoke_I1(Object a0) throws Throwable { return convert_I(invoker.<int >invoke(target, a0)); }
protected Object invoke_J1(Object a0) throws Throwable { return convert_J(invoker.<long >invoke(target, a0)); }
protected Object invoke_F1(Object a0) throws Throwable { return convert_F(invoker.<float >invoke(target, a0)); }
protected Object invoke_D1(Object a0) throws Throwable { return convert_D(invoker.<double>invoke(target, a0)); }
}
static class A2 extends Adapter {
protected A2(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -522,11 +527,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
protected Object invoke_I2(Object a0, Object a1) { return convert_I(invoker.<int >invoke(target, a0, a1)); }
protected Object invoke_J2(Object a0, Object a1) { return convert_J(invoker.<long >invoke(target, a0, a1)); }
protected Object invoke_F2(Object a0, Object a1) { return convert_F(invoker.<float >invoke(target, a0, a1)); }
protected Object invoke_D2(Object a0, Object a1) { return convert_D(invoker.<double>invoke(target, a0, a1)); }
protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1)); }
protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1)); }
protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1)); }
protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1)); }
}
static class A3 extends Adapter {
protected A3(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -534,11 +539,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2)); }
protected Object invoke_I3(Object a0, Object a1, Object a2) { return convert_I(invoker.<int >invoke(target, a0, a1, a2)); }
protected Object invoke_J3(Object a0, Object a1, Object a2) { return convert_J(invoker.<long >invoke(target, a0, a1, a2)); }
protected Object invoke_F3(Object a0, Object a1, Object a2) { return convert_F(invoker.<float >invoke(target, a0, a1, a2)); }
protected Object invoke_D3(Object a0, Object a1, Object a2) { return convert_D(invoker.<double>invoke(target, a0, a1, a2)); }
protected Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2)); }
protected Object invoke_I3(Object a0, Object a1, Object a2) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2)); }
protected Object invoke_J3(Object a0, Object a1, Object a2) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2)); }
protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2)); }
protected Object invoke_D3(Object a0, Object a1, Object a2) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2)); }
}
static class A4 extends Adapter {
protected A4(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -546,11 +551,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3)); }
protected Object invoke_I4(Object a0, Object a1, Object a2, Object a3) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3)); }
protected Object invoke_J4(Object a0, Object a1, Object a2, Object a3) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3)); }
protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3)); }
protected Object invoke_D4(Object a0, Object a1, Object a2, Object a3) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3)); }
protected Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3)); }
protected Object invoke_I4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3)); }
protected Object invoke_J4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3)); }
protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3)); }
protected Object invoke_D4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3)); }
}
static class A5 extends Adapter {
protected A5(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -558,11 +563,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4)); }
protected Object invoke_I5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4)); }
protected Object invoke_J5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4)); }
protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4)); }
protected Object invoke_D5(Object a0, Object a1, Object a2, Object a3, Object a4) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4)); }
protected Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_L(invoker.<Object>invoke(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(invoker.<int >invoke(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(invoker.<long >invoke(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(invoker.<float >invoke(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(invoker.<double>invoke(target, a0, a1, a2, a3, a4)); }
}
static class A6 extends Adapter {
protected A6(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -570,11 +575,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5)); }
protected Object invoke_I6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_I(invoker.<int >invoke(target, a0, a1, a2, a3, a4, a5)); }
protected Object invoke_J6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_J(invoker.<long >invoke(target, a0, a1, a2, a3, a4, a5)); }
protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_F(invoker.<float >invoke(target, a0, a1, a2, a3, a4, a5)); }
protected Object invoke_D6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5)); }
protected Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_L(invoker.<Object>invoke(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(invoker.<int >invoke(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(invoker.<long >invoke(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(invoker.<float >invoke(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(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5)); }
}
static class A7 extends Adapter {
protected A7(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -582,11 +587,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(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) { return convert_I(invoker.<int >invoke(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) { return convert_J(invoker.<long >invoke(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) { return convert_F(invoker.<float >invoke(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) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
protected Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_L(invoker.<Object>invoke(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(invoker.<int >invoke(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(invoker.<long >invoke(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(invoker.<float >invoke(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(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6)); }
}
static class A8 extends Adapter {
protected A8(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -594,11 +599,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(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) { return convert_I(invoker.<int >invoke(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) { return convert_J(invoker.<long >invoke(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) { return convert_F(invoker.<float >invoke(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) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
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(invoker.<Object>invoke(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(invoker.<int >invoke(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(invoker.<long >invoke(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(invoker.<float >invoke(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(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
}
static class A9 extends Adapter {
protected A9(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -606,11 +611,11 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(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) { return convert_I(invoker.<int >invoke(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) { return convert_J(invoker.<long >invoke(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) { return convert_F(invoker.<float >invoke(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) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
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(invoker.<Object>invoke(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(invoker.<int >invoke(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(invoker.<long >invoke(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(invoker.<float >invoke(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(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
}
static class A10 extends Adapter {
protected A10(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
......@@ -618,10 +623,10 @@ class genclasses {
{ 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) { return convert_L(invoker.<Object>invoke(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) { return convert_I(invoker.<int >invoke(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) { return convert_J(invoker.<long >invoke(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) { return convert_F(invoker.<float >invoke(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) { return convert_D(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
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(invoker.<Object>invoke(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(invoker.<int >invoke(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(invoker.<long >invoke(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(invoker.<float >invoke(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(invoker.<double>invoke(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
}
}
......@@ -44,16 +44,20 @@ public class Invokers {
// 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[] varargsInvokers;
/** Compute and cache information common to all collecting adapters
* that implement members of the erasure-family of the given erased type.
*/
public Invokers(Access token, MethodType targetType) {
Access.check(token);
this.targetType = targetType;
this.varargsInvokers = new MethodHandle[targetType.parameterCount()+1];
}
public static MethodType invokerType(MethodType targetType) {
return targetType.insertParameterType(0, MethodHandle.class);
return targetType.insertParameterTypes(0, MethodHandle.class);
}
public MethodHandle exactInvoker() {
......@@ -76,8 +80,14 @@ public class Invokers {
return invoker;
}
public MethodHandle varargsInvoker() {
throw new UnsupportedOperationException("NYI");
public MethodHandle varargsInvoker(int objectArgCount) {
MethodHandle vaInvoker = varargsInvokers[objectArgCount];
if (vaInvoker != null) return vaInvoker;
MethodHandle gInvoker = genericInvoker();
MethodType vaType = MethodType.genericMethodType(objectArgCount, true);
vaInvoker = MethodHandles.spreadArguments(gInvoker, invokerType(vaType));
varargsInvokers[objectArgCount] = vaInvoker;
return vaInvoker;
}
public String toString() {
......
......@@ -25,7 +25,7 @@
package sun.dyn;
import sun.dyn.util.BytecodeSignature;
import sun.dyn.util.BytecodeDescriptor;
import java.dyn.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
......@@ -33,6 +33,7 @@ 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;
......@@ -93,7 +94,7 @@ public final class MemberName implements Member, Cloneable {
}
if (type instanceof String) {
String sig = (String) type;
MethodType res = MethodType.fromBytecodeString(sig, getClassLoader());
MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
this.type = res;
return res;
}
......@@ -101,7 +102,7 @@ public final class MemberName implements Member, Cloneable {
Object[] typeInfo = (Object[]) type;
Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
Class<?> rtype = (Class<?>) typeInfo[0];
MethodType res = MethodType.make(rtype, ptypes);
MethodType res = MethodType.methodType(rtype, ptypes);
this.type = res;
return res;
}
......@@ -111,7 +112,7 @@ public final class MemberName implements Member, Cloneable {
public MethodType getInvocationType() {
MethodType itype = getMethodType();
if (!isStatic())
itype = itype.insertParameterType(0, clazz);
itype = itype.insertParameterTypes(0, clazz);
return itype;
}
......@@ -135,7 +136,7 @@ public final class MemberName implements Member, Cloneable {
}
if (type instanceof String) {
String sig = (String) type;
MethodType mtype = MethodType.fromBytecodeString("()"+sig, getClassLoader());
MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
Class<?> res = mtype.returnType();
this.type = res;
return res;
......@@ -155,9 +156,9 @@ public final class MemberName implements Member, Cloneable {
if (type instanceof String)
return (String) type;
if (isInvocable())
return BytecodeSignature.unparse(getMethodType());
return BytecodeDescriptor.unparse(getMethodType());
else
return BytecodeSignature.unparse(getFieldType());
return BytecodeDescriptor.unparse(getFieldType());
}
public int getModifiers() {
......@@ -353,6 +354,8 @@ public final class MemberName implements Member, Cloneable {
return type.toString(); // class java.lang.String
// else it is a field, method, or constructor
StringBuilder buf = new StringBuilder();
if (!isResolved())
buf.append("*.");
if (getDeclaringClass() != null) {
buf.append(getName(clazz));
buf.append('.');
......@@ -381,7 +384,7 @@ public final class MemberName implements Member, Cloneable {
private static String getName(Object obj) {
if (obj instanceof Class<?>)
return ((Class<?>)obj).getName();
return obj.toString();
return String.valueOf(obj);
}
// Queries to the JVM:
......@@ -408,6 +411,9 @@ public final class MemberName implements Member, Cloneable {
public static NoAccessException newNoAccessException(MemberName name, Class<?> lookupClass) {
return newNoAccessException("cannot access", name, lookupClass);
}
public static NoAccessException newNoAccessException(MemberName name, MethodHandles.Lookup lookup) {
return newNoAccessException(name, lookup.lookupClass());
}
public static NoAccessException newNoAccessException(String message,
MemberName name, Class<?> lookupClass) {
message += ": " + name;
......@@ -436,7 +442,7 @@ public final class MemberName implements Member, Cloneable {
matchFlags &= ALLOWED_FLAGS;
String matchSig = null;
if (matchType != null) {
matchSig = BytecodeSignature.unparse(matchType);
matchSig = BytecodeDescriptor.unparse(matchType);
if (matchSig.startsWith("("))
matchFlags &= ~(ALL_KINDS & ~IS_INVOCABLE);
else
......@@ -447,17 +453,18 @@ public final class MemberName implements Member, Cloneable {
MemberName[] buf = newMemberBuffer(len1);
int totalCount = 0;
ArrayList<MemberName[]> bufs = null;
int bufCount = 0;
for (;;) {
int bufCount = MethodHandleNatives.getMembers(defc,
bufCount = MethodHandleNatives.getMembers(defc,
matchName, matchSig, matchFlags,
lookupClass,
totalCount, buf);
if (bufCount <= buf.length) {
if (bufCount >= 0)
totalCount += bufCount;
if (bufCount < 0) bufCount = 0;
totalCount += bufCount;
break;
}
// JVM returned tp us with an intentional overflow!
// JVM returned to us with an intentional overflow!
totalCount += buf.length;
int excess = bufCount - buf.length;
if (bufs == null) bufs = new ArrayList<MemberName[]>(1);
......@@ -473,7 +480,7 @@ public final class MemberName implements Member, Cloneable {
Collections.addAll(result, buf0);
}
}
Collections.addAll(result, buf);
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.
......
......@@ -25,12 +25,25 @@
package sun.dyn;
import java.dyn.JavaMethodHandle;
import java.dyn.MethodHandle;
import java.dyn.MethodHandles;
import java.dyn.MethodHandles.Lookup;
import java.dyn.MethodType;
import java.util.logging.Level;
import java.util.logging.Logger;
import sun.dyn.util.VerifyType;
import java.dyn.NoAccessException;
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;
......@@ -57,6 +70,25 @@ public abstract class MethodHandleImpl {
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.
......@@ -106,8 +138,8 @@ public abstract class MethodHandleImpl {
}
static {
// Force initialization:
Lookup.PUBLIC_LOOKUP.lookupClass();
// Force initialization of Lookup, so it calls us back as initLookup:
MethodHandles.publicLookup();
if (IMPL_LOOKUP_INIT == null)
throw new InternalError();
}
......@@ -151,7 +183,7 @@ public abstract class MethodHandleImpl {
// 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.insertParameterType(0, recvType);
mtype = mtype.insertParameterTypes(0, recvType);
if (method.isConstructor())
doDispatch = true;
// FIXME: JVM has trouble building MH.invoke sites for
......@@ -170,21 +202,223 @@ public abstract class MethodHandleImpl {
public static
MethodHandle accessField(Access token,
MemberName member, boolean isSetter,
Class<?> lookupClass) {
MemberName member, boolean isSetter,
Class<?> lookupClass) {
Access.check(token);
// FIXME: Use sun.misc.Unsafe to dig up the dirt on the field.
throw new UnsupportedOperationException("Not yet implemented");
// 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) {
Class<?> arrayClass, boolean isSetter) {
Access.check(token);
if (!arrayClass.isArray())
throw newIllegalArgumentException("not an array: "+arrayClass);
// FIXME: Use sun.misc.Unsafe to dig up the dirt on the array.
throw new UnsupportedOperationException("Not yet implemented");
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<C,V> extends JavaMethodHandle {
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(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 name; }
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) {
Error e = new InternalError();
e.initCause(ee);
throw e;
}
}
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 (NoAccessException ee) {
Error e = new InternalError("name,type="+name+type);
e.initCause(ee);
throw e;
}
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<Class<?>, MethodHandle[]> ARRAY_CACHE =
new HashMap<Class<?>, 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> V getElementL(Class<V[]> aclass, V[] a, int i) { return aclass.cast(a)[i]; }
static <V> void setElementL(Class<V[]> 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 (NoAccessException ee) {
Error e = new InternalError("name,type="+name+type);
e.initCause(ee);
throw e;
}
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.
......@@ -203,8 +437,11 @@ public abstract class MethodHandleImpl {
if (info instanceof DirectMethodHandle) {
DirectMethodHandle dmh = (DirectMethodHandle) info;
if (receiver == null ||
dmh.type().parameterType(0).isAssignableFrom(receiver.getClass()))
target = dmh;
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)
......@@ -223,7 +460,7 @@ public abstract class MethodHandleImpl {
MethodHandle bindArgument(Access token,
MethodHandle target, int argnum, Object receiver) {
Access.check(token);
throw new UnsupportedOperationException("NYI");
return new BoundMethodHandle(target, receiver, argnum);
}
public static MethodHandle convertArguments(Access token,
......@@ -232,6 +469,189 @@ public abstract class MethodHandleImpl {
MethodType oldType,
int[] permutationOrNull) {
Access.check(token);
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<Integer> goal = new ArrayList<Integer>(); // i*TOKEN
List<Integer> state = new ArrayList<Integer>(); // i*TOKEN
List<Integer> drops = new ArrayList<Integer>(); // not tokens
List<Integer> dups = new ArrayList<Integer>(); // 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<Integer> 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<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy);
MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes);
MethodHandle nextTarget
= AdapterMethodHandle.makeRotateArguments(token, 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<Class<?>> 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(token, 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<Class<?>> ptypes = oldType.parameterList();
ptypes = ptypes.subList(0, ptypes.size() - dupArgCount);
MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes);
target = AdapterMethodHandle.makeDupArguments(token, 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<Class<?>> dropTypes = newType.parameterList()
.subList(dropArgPos, dropArgPos + dropArgCount);
MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes);
target = AdapterMethodHandle.makeDropArguments(token, 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(token, newType, target);
if (res != null)
return res;
......@@ -241,7 +661,7 @@ public abstract class MethodHandleImpl {
// 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.makeGeneric(argc);
MethodType objType = MethodType.genericMethodType(argc);
MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(token, objType, target);
if (objTarget == null)
objTarget = FromGeneric.make(target);
......@@ -272,83 +692,386 @@ public abstract class MethodHandleImpl {
Class<?>[] ptypes = oldType.parameterArray();
for (int i = 0; i < spreadCount; i++)
ptypes[spreadArg + i] = VerifyType.spreadArgElementType(spreadType, i);
MethodType midType = MethodType.make(newType.returnType(), ptypes);
MethodType midType = MethodType.methodType(newType.returnType(), ptypes);
// after spreading, some arguments may need further conversion
target = convertArguments(token, target, midType, oldType, null);
if (target == null)
MethodHandle target2 = convertArguments(token, target, midType, oldType, null);
if (target2 == null)
throw new UnsupportedOperationException("NYI: convert "+midType+" =calls=> "+oldType);
res = AdapterMethodHandle.makeSpreadArguments(token, newType, target, spreadArgType, spreadArg, spreadCount);
res = AdapterMethodHandle.makeSpreadArguments(token, newType, target2, spreadArgType, spreadArg, spreadCount);
if (res != null)
return res;
res = SpreadGeneric.make(target2, spreadCount);
if (res != null)
res = convertArguments(token, res, newType, res.type(), null);
return res;
}
public static MethodHandle collectArguments(Access token,
MethodHandle target,
MethodType newType,
int collectArg) {
if (collectArg > 0)
throw new UnsupportedOperationException("NYI");
throw new UnsupportedOperationException("NYI");
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(token, target, oldType.generic(), oldType, null);
MethodHandle gcollector = convertArguments(token, collector, colType.generic(), colType, null);
if (gtarget == null || gcollector == null) return null;
MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget);
MethodHandle result = convertArguments(token, gresult, newType, gresult.type(), null);
return result;
}
public static MethodHandle filterArgument(Access token,
MethodHandle target,
int pos,
MethodHandle filter) {
Access.check(token);
MethodType ttype = target.type(), gttype = ttype.generic();
if (ttype != gttype) {
target = convertArguments(token, 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(token, filter, gftype, ftype, null);
ftype = gftype;
}
if (ftype == ttype) {
// simple unary case
return FilterOneArgument.make(filter, target);
}
return FilterGeneric.makeArgumentFilter(pos, filter, target);
}
public static MethodHandle foldArguments(Access token,
MethodHandle target,
MethodType newType,
MethodHandle combiner) {
Access.check(token);
MethodType oldType = target.type();
MethodType ctype = combiner.type();
MethodHandle gtarget = convertArguments(token, target, oldType.generic(), oldType, null);
MethodHandle gcombiner = convertArguments(token, combiner, ctype.generic(), ctype, null);
if (gtarget == null || gcombiner == null) return null;
MethodHandle gresult = FilterGeneric.makeArgumentFolder(gcombiner, gtarget);
MethodHandle result = convertArguments(token, gresult, newType, gresult.type(), null);
return result;
}
public static
MethodHandle dropArguments(Access token, MethodHandle target,
MethodType newType, int argnum) {
Access.check(token);
int drops = newType.parameterCount() - target.type().parameterCount();
MethodHandle res = AdapterMethodHandle.makeDropArguments(token, newType, target, argnum, drops);
if (res != null)
return res;
throw new UnsupportedOperationException("NYI");
}
private static class GuardWithTest extends JavaMethodHandle {
private final MethodHandle test, target, fallback;
public GuardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback) {
this(INVOKES[target.type().parameterCount()], test, target, fallback);
}
public GuardWithTest(MethodHandle invoker,
MethodHandle test, MethodHandle target, MethodHandle fallback) {
super(invoker);
this.test = test;
this.target = target;
this.fallback = fallback;
}
@Override
public String toString() {
return target.toString();
}
private Object invoke_V(Object... av) throws Throwable {
if (test.<boolean>invoke(av))
return target.<Object>invoke(av);
return fallback.<Object>invoke(av);
}
private Object invoke_L0() throws Throwable {
if (test.<boolean>invoke())
return target.<Object>invoke();
return fallback.<Object>invoke();
}
private Object invoke_L1(Object a0) throws Throwable {
if (test.<boolean>invoke(a0))
return target.<Object>invoke(a0);
return fallback.<Object>invoke(a0);
}
private Object invoke_L2(Object a0, Object a1) throws Throwable {
if (test.<boolean>invoke(a0, a1))
return target.<Object>invoke(a0, a1);
return fallback.<Object>invoke(a0, a1);
}
private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
if (test.<boolean>invoke(a0, a1, a2))
return target.<Object>invoke(a0, a1, a2);
return fallback.<Object>invoke(a0, a1, a2);
}
private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
if (test.<boolean>invoke(a0, a1, a2, a3))
return target.<Object>invoke(a0, a1, a2, a3);
return fallback.<Object>invoke(a0, a1, a2, a3);
}
private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
if (test.<boolean>invoke(a0, a1, a2, a3, a4))
return target.<Object>invoke(a0, a1, a2, a3, a4);
return fallback.<Object>invoke(a0, a1, a2, a3, a4);
}
private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
if (test.<boolean>invoke(a0, a1, a2, a3, a4, a5))
return target.<Object>invoke(a0, a1, a2, a3, a4, a5);
return fallback.<Object>invoke(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 (test.<boolean>invoke(a0, a1, a2, a3, a4, a5, a6))
return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6);
return fallback.<Object>invoke(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 (test.<boolean>invoke(a0, a1, a2, a3, a4, a5, a6, a7))
return target.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7);
return fallback.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7);
}
static MethodHandle[] makeInvokes() {
ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>();
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 (NoAccessException 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 (NoAccessException ex) {
throw new InternalError("");
}
}
}
public static
MethodHandle makeGuardWithTest(Access token,
final MethodHandle test,
final MethodHandle target,
final MethodHandle fallback) {
MethodHandle test,
MethodHandle target,
MethodHandle fallback) {
Access.check(token);
// %%% This is just a sketch. It needs to be de-boxed.
// Adjust the handles to accept varargs lists.
MethodType type = target.type();
Class<?> rtype = type.returnType();
if (type.parameterCount() != 1 || type.parameterType(0).isPrimitive()) {
MethodType vatestType = MethodType.make(boolean.class, Object[].class);
MethodType vatargetType = MethodType.make(rtype, Object[].class);
MethodHandle vaguard = makeGuardWithTest(token,
MethodHandles.spreadArguments(test, vatestType),
MethodHandles.spreadArguments(target, vatargetType),
MethodHandles.spreadArguments(fallback, vatargetType));
return MethodHandles.collectArguments(vaguard, type);
}
if (rtype.isPrimitive()) {
MethodType boxtype = type.changeReturnType(Object.class);
MethodHandle boxguard = makeGuardWithTest(token,
test,
MethodHandles.convertArguments(target, boxtype),
MethodHandles.convertArguments(fallback, boxtype));
return MethodHandles.convertArguments(boxguard, type);
}
// Got here? Reduced calling sequence to Object(Object).
class Guarder {
Object invoke(Object x) {
// If javac supports MethodHandle.invoke directly:
//z = vatest.invoke<boolean>(arguments);
// If javac does not support direct MH.invoke calls:
boolean z = (Boolean) MethodHandles.invoke_1(test, x);
MethodHandle mh = (z ? target : fallback);
return MethodHandles.invoke_1(mh, x);
int nargs = type.parameterCount();
if (nargs < GuardWithTest.INVOKES.length) {
MethodType gtype = type.generic();
MethodHandle gtest = convertArguments(token, test, gtype.changeReturnType(boolean.class), test.type(), null);
MethodHandle gtarget = convertArguments(token, target, gtype, type, null);
MethodHandle gfallback = convertArguments(token, fallback, gtype, type, null);
if (gtest == null || gtarget == null || gfallback == null) return null;
MethodHandle gguard = new GuardWithTest(gtest, gtarget, gfallback);
return convertArguments(token, gguard, type, gtype, null);
} else {
MethodType gtype = MethodType.genericMethodType(0, true);
MethodHandle gtest = spreadArguments(token, test, gtype.changeReturnType(boolean.class), 0);
MethodHandle gtarget = spreadArguments(token, target, gtype, 0);
MethodHandle gfallback = spreadArguments(token, fallback, gtype, 0);
MethodHandle gguard = new GuardWithTest(GuardWithTest.VARARGS_INVOKE, gtest, gtarget, gfallback);
if (gtest == null || gtarget == null || gfallback == null) return null;
return collectArguments(token, gguard, type, 0, null);
}
}
private static class GuardWithCatch extends JavaMethodHandle {
private final MethodHandle target;
private final Class<? extends Throwable> exType;
private final MethodHandle catcher;
public GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
this(INVOKES[target.type().parameterCount()], target, exType, catcher);
}
public 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 target.toString();
}
private Object invoke_V(Object... av) throws Throwable {
try {
return target.<Object>invoke(av);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(t, av);
}
MethodHandle handle() {
MethodType invokeType = MethodType.makeGeneric(0, true);
MethodHandle vh = IMPL_LOOKUP.bind(this, "invoke", invokeType);
return MethodHandles.collectArguments(vh, target.type());
}
private Object invoke_L0() throws Throwable {
try {
return target.<Object>invoke();
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(t);
}
}
private Object invoke_L1(Object a0) throws Throwable {
try {
return target.<Object>invoke(a0);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(t, a0);
}
}
return new Guarder().handle();
private Object invoke_L2(Object a0, Object a1) throws Throwable {
try {
return target.<Object>invoke(a0, a1);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(t, a0, a1);
}
}
private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
try {
return target.<Object>invoke(a0, a1, a2);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(t, a0, a1, a2);
}
}
private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
try {
return target.<Object>invoke(a0, a1, a2, a3);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(t, a0, a1, a2, a3);
}
}
private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
try {
return target.<Object>invoke(a0, a1, a2, a3, a4);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(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.<Object>invoke(a0, a1, a2, a3, a4, a5);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(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.<Object>invoke(a0, a1, a2, a3, a4, a5, a6);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(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.<Object>invoke(a0, a1, a2, a3, a4, a5, a6, a7);
} catch (Throwable t) {
if (!exType.isInstance(t)) throw t;
return catcher.<Object>invoke(t, a0, a1, a2, a3, a4, a5, a6, a7);
}
}
static MethodHandle[] makeInvokes() {
ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>();
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 (NoAccessException 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 (NoAccessException ex) {
throw new InternalError("");
}
}
}
public static
MethodHandle makeGuardWithCatch(Access token,
MethodHandle target,
Class<? extends Throwable> exType,
MethodHandle catcher) {
Access.check(token);
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(token, target, gtype, type, null);
MethodHandle gcatcher = convertArguments(token, catcher, gcatchType, ctype, null);
MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher);
if (gtarget == null || gcatcher == null || gguard == null) return null;
return convertArguments(token, gguard, type, gtype, null);
} else {
MethodType gtype = MethodType.genericMethodType(0, true);
MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
MethodHandle gtarget = spreadArguments(token, target, gtype, 0);
MethodHandle gcatcher = spreadArguments(token, catcher, gcatchType, 1);
MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher);
if (gtarget == null || gcatcher == null || gguard == null) return null;
return collectArguments(token, gguard, type, 0, null);
}
}
public static
MethodHandle combineArguments(Access token, MethodHandle target, MethodHandle checker, int pos) {
MethodHandle throwException(Access token, MethodType type) {
Access.check(token);
throw new UnsupportedOperationException("Not yet implemented");
return AdapterMethodHandle.makeRetypeRaw(token, type, THROW_EXCEPTION);
}
protected static String basicToString(MethodHandle target) {
static final MethodHandle THROW_EXCEPTION
= IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
MethodType.methodType(Empty.class, Throwable.class));
static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
public static String getNameString(Access token, MethodHandle target) {
Access.check(token);
MemberName name = null;
if (target != null)
name = MethodHandleNatives.getMethodName(target);
......@@ -357,17 +1080,30 @@ public abstract class MethodHandleImpl {
return name.getName();
}
protected static String addTypeString(MethodHandle target, String name) {
if (target == null) return name;
return name+target.type();
public static String addTypeString(MethodHandle target) {
if (target == null) return "null";
return target.toString() + target.type();
}
static RuntimeException newIllegalArgumentException(String string) {
return new IllegalArgumentException(string);
public static void checkSpreadArgument(Object av, int n) {
if (av == null ? n != 0 : ((Object[])av).length != n)
throw newIllegalArgumentException("Array is not of length "+n);
}
@Override
public String toString() {
MethodHandle self = (MethodHandle) this;
return addTypeString(self, basicToString(self));
public 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);
}
}
}
......@@ -25,6 +25,7 @@
package sun.dyn;
import java.dyn.CallSite;
import java.dyn.MethodHandle;
import java.dyn.MethodType;
import java.lang.reflect.AccessibleObject;
......@@ -60,7 +61,7 @@ class MethodHandleNatives {
static native void init(MethodType self);
/** Tell the JVM that we need to change the target of an invokedynamic. */
static native void linkCallSite(CallSiteImpl site, MethodHandle target);
static native void linkCallSite(CallSite site, MethodHandle target);
/** Fetch the vmtarget field.
* It will be sanitized as necessary to avoid exposing non-Java references.
......@@ -84,8 +85,7 @@ class MethodHandleNatives {
}
/** Fetch the target of this method handle.
* If it directly targets a method, return a tuple of method info.
* The info is of the form new Object[]{defclass, name, sig, refclass}.
* 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) {
......@@ -123,7 +123,7 @@ class MethodHandleNatives {
registerNatives();
JVM_SUPPORT_ = true;
JVM_PUSH_LIMIT_ = getConstant(Constants.GC_JVM_PUSH_LIMIT);
JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_LIMIT);
JVM_STACK_MOVE_UNIT_ = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT);
//sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
} catch (UnsatisfiedLinkError ee) {
// ignore; if we use init() methods later we'll see linkage errors
......@@ -149,7 +149,7 @@ class MethodHandleNatives {
// MethodHandleImpl
static final int // for getConstant
GC_JVM_PUSH_LIMIT = 0,
GC_JVM_STACK_MOVE_LIMIT = 1;
GC_JVM_STACK_MOVE_UNIT = 1;
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)
......@@ -178,19 +178,20 @@ class MethodHandleNatives {
*/
static final int
OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
OP_CHECK_CAST = 0x1, // ref-to-ref conversion; requires a Class argument
OP_PRIM_TO_PRIM = 0x2, // converts from one primitive to another
OP_REF_TO_PRIM = 0x3, // unboxes a wrapper to produce a primitive
OP_PRIM_TO_REF = 0x4, // boxes a primitive into a wrapper (NYI)
OP_SWAP_ARGS = 0x5, // swap arguments (vminfo is 2nd arg)
OP_ROT_ARGS = 0x6, // rotate arguments (vminfo is displaced arg)
OP_DUP_ARGS = 0x7, // duplicates one or more arguments (at TOS)
OP_DROP_ARGS = 0x8, // remove one or more argument slots
OP_COLLECT_ARGS = 0x9, // combine one or more arguments into a varargs (NYI)
OP_SPREAD_ARGS = 0xA, // expand in place a varargs array (of known size)
OP_FLYBY = 0xB, // operate first on reified argument list (NYI)
OP_RICOCHET = 0xC, // run an adapter chain on the return value (NYI)
CONV_OP_LIMIT = 0xD; // limit of CONV_OP enumeration
OP_RETYPE_RAW = 0x1, // no argument changes; straight retype
OP_CHECK_CAST = 0x2, // ref-to-ref conversion; requires a Class argument
OP_PRIM_TO_PRIM = 0x3, // converts from one primitive to another
OP_REF_TO_PRIM = 0x4, // unboxes a wrapper to produce a primitive
OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper (NYI)
OP_SWAP_ARGS = 0x6, // swap arguments (vminfo is 2nd arg)
OP_ROT_ARGS = 0x7, // rotate arguments (vminfo is displaced arg)
OP_DUP_ARGS = 0x8, // duplicates one or more arguments (at TOS)
OP_DROP_ARGS = 0x9, // remove one or more argument slots
OP_COLLECT_ARGS = 0xA, // combine one or more arguments into a varargs (NYI)
OP_SPREAD_ARGS = 0xB, // expand in place a varargs array (of known size)
OP_FLYBY = 0xC, // operate first on reified argument list (NYI)
OP_RICOCHET = 0xD, // run an adapter chain on the return value (NYI)
CONV_OP_LIMIT = 0xE; // limit of CONV_OP enumeration
/** Shift and mask values for decoding the AMH.conversion field.
* These numbers are shared with the JVM for creating AMHs.
*/
......@@ -209,6 +210,7 @@ class MethodHandleNatives {
// TODO: The following expression should be replaced by
// a JVM query.
((1<<OP_RETYPE_ONLY)
|(1<<OP_RETYPE_RAW)
|(1<<OP_CHECK_CAST)
|(1<<OP_PRIM_TO_PRIM)
|(1<<OP_REF_TO_PRIM)
......@@ -216,6 +218,7 @@ class MethodHandleNatives {
|(1<<OP_ROT_ARGS)
|(1<<OP_DUP_ARGS)
|(1<<OP_DROP_ARGS)
//|(1<<OP_SPREAD_ARGS) // FIXME: Check JVM assembly code.
);
/**
......
......@@ -27,6 +27,7 @@ package sun.dyn;
import java.dyn.*;
import sun.dyn.util.Wrapper;
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* Shared information for a group of method types, which differ
......@@ -56,8 +57,8 @@ public class MethodTypeImpl {
// 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*/ Invokers invokers; // cache of handy higher-order adapters
public MethodType erasedType() {
return erasedType;
......@@ -68,7 +69,7 @@ public class MethodTypeImpl {
}
/** Access methods for the internals of MethodType, supplied to
* MethodTypeForm as a trusted agent.
* MethodTypeImpl as a trusted agent.
*/
static public interface MethodTypeFriend {
Class<?>[] ptypes(MethodType mt);
......@@ -150,7 +151,7 @@ public class MethodTypeImpl {
this.argToSlotTable = argToSlotTab;
this.slotToArgTable = slotToArgTab;
if (pslotCount >= 256) throw new IllegalArgumentException("too many arguments");
if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments");
// send a few bits down to the JVM:
this.vmslots = parameterSlotCount();
......@@ -378,10 +379,10 @@ public class MethodTypeImpl {
static MethodTypeImpl findForm(MethodType mt) {
MethodType erased = canonicalize(mt, ERASE, ERASE);
if (erased == null) {
// It is already erased. Make a new MethodTypeForm.
// It is already erased. Make a new MethodTypeImpl.
return METHOD_TYPE_FRIEND.newMethodTypeForm(mt);
} else {
// Share the MethodTypeForm with the erased version.
// Share the MethodTypeImpl with the erased version.
return METHOD_TYPE_FRIEND.form(erased);
}
}
......
/*
* Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.dyn;
import java.dyn.JavaMethodHandle;
import java.dyn.MethodHandle;
import java.dyn.MethodHandles;
import java.dyn.MethodType;
import java.dyn.NoAccessException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import sun.dyn.util.ValueConversions;
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* 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<Class<?>> 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);
MethodTypeImpl form = MethodTypeImpl.of(targetType);
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) {
MethodHandleImpl.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 = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
} catch (NoAccessException 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 JavaMethodHandle {
/*
* class X<<R,int M,int N>> 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 target.toString();
}
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; // "sun.dyn.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.<Object>invoke(a0, a1)); }
protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av,1);
return target.<Object>invoke(a0,
super.select(av,0)); }
protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av,1);
return target.<Object>invoke(
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.<Object>invoke(@av@); }",
" //@each-S@",
" protected Object invoke_S@S@(@Tvav,@Object av) throws Throwable { av = super.check(av, @S@);",
" return target.<Object>invoke(@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.<Object>invoke(); }
}
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.<Object>invoke(a0); }
protected Object invoke_S1(Object av) throws Throwable { av = super.check(av, 1);
return target.<Object>invoke(
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.<Object>invoke(a0, a1); }
protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av, 1);
return target.<Object>invoke(a0,
super.select(av,0)); }
protected Object invoke_S2(Object av) throws Throwable { av = super.check(av, 2);
return target.<Object>invoke(
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.<Object>invoke(a0, a1, a2); }
protected Object invoke_S1(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 1);
return target.<Object>invoke(a0, a1,
super.select(av,0)); }
protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av, 2);
return target.<Object>invoke(a0,
super.select(av,0), super.select(av,1)); }
protected Object invoke_S3(Object av) throws Throwable { av = super.check(av, 3);
return target.<Object>invoke(
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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(
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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(
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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(
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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(
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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(
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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(
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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(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.<Object>invoke(
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)); }
}
}
......@@ -34,6 +34,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import sun.dyn.util.ValueConversions;
import sun.dyn.util.Wrapper;
import static sun.dyn.MemberName.newIllegalArgumentException;
/**
* Adapters which mediate between incoming calls which are not generic
......@@ -68,7 +69,7 @@ class ToGeneric {
// conversion which unboxes a primitive return value
private final MethodHandle returnConversion;
/** Compute and cache information common to all collecting adapters
/** 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) {
......@@ -111,30 +112,48 @@ class ToGeneric {
// primitive arguments according to their "raw" types int/long
MethodType intsAtEnd = MethodTypeImpl.of(primsAtEnd).primsAsInts();
ad = findAdapter(rawEntryTypeInit = intsAtEnd);
if (ad == null) {
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 = MethodTypeImpl.of(primsAtEnd).primsAsLongs();
ad = findAdapter(rawEntryTypeInit = longsAtEnd);
if (ad == null) {
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 = MethodHandle.convertArguments(Access.TOKEN,
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();
}
}
MethodHandle rawEntryPoint = ad.prototypeEntryPoint();
MethodType tepType = entryType.insertParameterType(0, ad.getClass());
MethodType tepType = entryType.insertParameterTypes(0, ad.getClass());
this.entryPoint =
AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN, tepType, rawEntryPoint);
AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, tepType, rawEntryPoint);
if (this.entryPoint == null)
throw new UnsupportedOperationException("cannot retype to "+entryType
+" from "+rawEntryPoint.type().dropParameterType(0));
+" from "+rawEntryPoint.type().dropParameterTypes(0, 1));
this.returnConversion = computeReturnConversion(entryType, rawEntryTypeInit, false);
this.rawEntryType = rawEntryTypeInit;
this.adapter = ad;
this.invoker = makeRawArgumentFilter(invoker0,
rawEntryPoint.type().dropParameterType(0), entryType);
this.invoker = makeRawArgumentFilter(invoker0, rawEntryTypeInit, entryType);
}
/** A generic argument list will be created by a call of type 'raw'.
......@@ -157,8 +176,8 @@ class ToGeneric {
if (filteredInvoker == null) throw new UnsupportedOperationException("NYI");
}
MethodHandle reboxer = ValueConversions.rebox(dst, false);
FilterGeneric gen = new FilterGeneric(filteredInvoker.type(), (short)(1+i), (short)1, 'R');
filteredInvoker = gen.makeInstance(reboxer, filteredInvoker);
filteredInvoker = FilterGeneric.makeArgumentFilter(1+i, reboxer, filteredInvoker);
if (filteredInvoker == null) throw new InternalError();
}
if (filteredInvoker == null) return invoker;
return AdapterMethodHandle.makeRetypeOnly(Access.TOKEN, invoker.type(), filteredInvoker);
......@@ -209,9 +228,9 @@ class ToGeneric {
if (convert == null)
convert = computeReturnConversion(type, rawEntryType, true);
// retype erased reference arguments (the cast makes it safe to do this)
MethodType tepType = type.insertParameterType(0, adapter.getClass());
MethodType tepType = type.insertParameterTypes(0, adapter.getClass());
MethodHandle typedEntryPoint =
AdapterMethodHandle.makeRawRetypeOnly(Access.TOKEN, tepType, entryPoint);
AdapterMethodHandle.makeRetypeRaw(Access.TOKEN, tepType, entryPoint);
return adapter.makeInstance(typedEntryPoint, invoker, convert, genericTarget);
}
......@@ -225,7 +244,7 @@ class ToGeneric {
public static MethodHandle make(MethodType type, MethodHandle genericTarget) {
MethodType gtype = genericTarget.type();
if (type.generic() != gtype)
throw new IllegalArgumentException();
throw newIllegalArgumentException("type must be generic");
if (type == gtype) return genericTarget;
return ToGeneric.of(type).makeInstance(type, genericTarget);
}
......@@ -283,7 +302,10 @@ class ToGeneric {
try {
return ctor.newInstance(entryPoint);
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException 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) {
}
......@@ -317,6 +339,11 @@ class ToGeneric {
protected final MethodHandle target; // Object... -> Object
protected final MethodHandle convert; // Object -> R
@Override
public String toString() {
return target.toString();
}
protected boolean isPrototype() { return target == null; }
/* Prototype constructor. */
protected Adapter(MethodHandle entryPoint) {
......@@ -344,33 +371,33 @@ class ToGeneric {
// { return new ThisType(entryPoint, convert, target); }
// Code to run when the arguments (<= 4) have all been boxed.
protected Object target() { return invoker.<Object>invoke(target); }
protected Object target(Object a0) { return invoker.<Object>invoke(target, a0); }
protected Object target() throws Throwable { return invoker.<Object>invoke(target); }
protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(target, a0); }
protected Object target(Object a0, Object a1)
{ return invoker.<Object>invoke(target, a0, a1); }
throws Throwable { return invoker.<Object>invoke(target, a0, a1); }
protected Object target(Object a0, Object a1, Object a2)
{ return invoker.<Object>invoke(target, a0, a1, a2); }
throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2); }
protected Object target(Object a0, Object a1, Object a2, Object a3)
{ return invoker.<Object>invoke(target, a0, a1, a2, a3); }
throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, a3); }
/*
protected Object target_0(Object... av) { return invoker.<Object>invoke(target, av); }
protected Object target_0(Object... av) throws Throwable { return invoker.<Object>invoke(target, av); }
protected Object target_1(Object a0, Object... av)
{ return invoker.<Object>invoke(target, a0, (Object)av); }
throws Throwable { return invoker.<Object>invoke(target, a0, (Object)av); }
protected Object target_2(Object a0, Object a1, Object... av)
{ return invoker.<Object>invoke(target, a0, a1, (Object)av); }
throws Throwable { return invoker.<Object>invoke(target, a0, a1, (Object)av); }
protected Object target_3(Object a0, Object a1, Object a2, Object... av)
{ return invoker.<Object>invoke(target, a0, a1, a2, (Object)av); }
throws Throwable { return invoker.<Object>invoke(target, a0, a1, a2, (Object)av); }
protected Object target_4(Object a0, Object a1, Object a2, Object a3, Object... av)
{ return invoker.<Object>invoke(target, a0, a1, a2, a3, (Object)av); }
throws Throwable { return invoker.<Object>invoke(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) { return convert.<Object>invoke(res); }
protected int return_I(Object res) { return convert.<int >invoke(res); }
protected long return_J(Object res) { return convert.<long >invoke(res); }
protected float return_F(Object res) { return convert.<float >invoke(res); }
protected double return_D(Object res) { return convert.<double>invoke(res); }
protected Object return_L(Object res) throws Throwable { return convert.<Object>invoke(res); }
protected int return_I(Object res) throws Throwable { return convert.<int >invoke(res); }
protected long return_J(Object res) throws Throwable { return convert.<long >invoke(res); }
protected float return_F(Object res) throws Throwable { return convert.<float >invoke(res); }
protected double return_D(Object res) throws Throwable { return convert.<double>invoke(res); }
static private final String CLASS_PREFIX; // "sun.dyn.ToGeneric$"
static {
......@@ -397,25 +424,25 @@ class ToGeneric {
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) { return invoker.<Object>invoke(target, a0); }
protected Object targetA1(Object a0) { return target(a0); }
protected Object targetA1(int a0) { return target(a0); }
protected Object targetA1(long a0) { return target(a0); }
protected Object invoke_L(Object a0) { return return_L(targetA1(a0)); }
protected int invoke_I(Object a0) { return return_I(targetA1(a0)); }
protected long invoke_J(Object a0) { return return_J(targetA1(a0)); }
protected float invoke_F(Object a0) { return return_F(targetA1(a0)); }
protected double invoke_D(Object a0) { return return_D(targetA1(a0)); }
protected Object invoke_L(int a0) { return return_L(targetA1(a0)); }
protected int invoke_I(int a0) { return return_I(targetA1(a0)); }
protected long invoke_J(int a0) { return return_J(targetA1(a0)); }
protected float invoke_F(int a0) { return return_F(targetA1(a0)); }
protected double invoke_D(int a0) { return return_D(targetA1(a0)); }
protected Object invoke_L(long a0) { return return_L(targetA1(a0)); }
protected int invoke_I(long a0) { return return_I(targetA1(a0)); }
protected long invoke_J(long a0) { return return_J(targetA1(a0)); }
protected float invoke_F(long a0) { return return_F(targetA1(a0)); }
protected double invoke_D(long a0) { return return_D(targetA1(a0)); }
protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(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)); }
}
// */
......@@ -435,13 +462,13 @@ class genclasses {
" 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@) { return invoker.<Object>invoke(target, @av@); }",
" protected Object target(@Ovav@) throws Throwable { return invoker.<Object>invoke(target, @av@); }",
" //@each-Tv@",
" protected Object target@cat@(@Tvav@) { return target(@av@); }",
" protected Object target@cat@(@Tvav@) throws Throwable { return target(@av@); }",
" //@end-Tv@",
" //@each-Tv@",
" //@each-R@",
" protected @R@ invoke_@Rc@(@Tvav@) { return return_@Rc@(target@cat@(@av@)); }",
" protected @R@ invoke_@Rc@(@Tvav@) throws Throwable { return return_@Rc@(target@cat@(@av@)); }",
" //@end-R@",
" //@end-Tv@",
" }",
......@@ -595,424 +622,424 @@ class genclasses {
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() { return invoker.<Object>invoke(target); }
protected Object targetA0() { return target(); }
protected Object invoke_L() { return return_L(targetA0()); }
protected int invoke_I() { return return_I(targetA0()); }
protected long invoke_J() { return return_J(targetA0()); }
protected float invoke_F() { return return_F(targetA0()); }
protected double invoke_D() { return return_D(targetA0()); }
protected Object target() throws Throwable { return invoker.<Object>invoke(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) { return invoker.<Object>invoke(target, a0); }
protected Object targetA1(Object a0) { return target(a0); }
protected Object targetA1(int a0) { return target(a0); }
protected Object targetA1(long a0) { return target(a0); }
protected Object invoke_L(Object a0) { return return_L(targetA1(a0)); }
protected int invoke_I(Object a0) { return return_I(targetA1(a0)); }
protected long invoke_J(Object a0) { return return_J(targetA1(a0)); }
protected float invoke_F(Object a0) { return return_F(targetA1(a0)); }
protected double invoke_D(Object a0) { return return_D(targetA1(a0)); }
protected Object invoke_L(int a0) { return return_L(targetA1(a0)); }
protected int invoke_I(int a0) { return return_I(targetA1(a0)); }
protected long invoke_J(int a0) { return return_J(targetA1(a0)); }
protected float invoke_F(int a0) { return return_F(targetA1(a0)); }
protected double invoke_D(int a0) { return return_D(targetA1(a0)); }
protected Object invoke_L(long a0) { return return_L(targetA1(a0)); }
protected int invoke_I(long a0) { return return_I(targetA1(a0)); }
protected long invoke_J(long a0) { return return_J(targetA1(a0)); }
protected float invoke_F(long a0) { return return_F(targetA1(a0)); }
protected double invoke_D(long a0) { return return_D(targetA1(a0)); }
protected Object target(Object a0) throws Throwable { return invoker.<Object>invoke(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) { return invoker.<Object>invoke(target, a0, a1); }
protected Object targetA2(Object a0, Object a1) { return target(a0, a1); }
protected Object targetA2(Object a0, int a1) { return target(a0, a1); }
protected Object targetA2(int a0, int a1) { return target(a0, a1); }
protected Object targetA2(Object a0, long a1) { return target(a0, a1); }
protected Object targetA2(long a0, long a1) { return target(a0, a1); }
protected Object invoke_L(Object a0, Object a1) { return return_L(targetA2(a0, a1)); }
protected int invoke_I(Object a0, Object a1) { return return_I(targetA2(a0, a1)); }
protected long invoke_J(Object a0, Object a1) { return return_J(targetA2(a0, a1)); }
protected float invoke_F(Object a0, Object a1) { return return_F(targetA2(a0, a1)); }
protected double invoke_D(Object a0, Object a1) { return return_D(targetA2(a0, a1)); }
protected Object invoke_L(Object a0, int a1) { return return_L(targetA2(a0, a1)); }
protected int invoke_I(Object a0, int a1) { return return_I(targetA2(a0, a1)); }
protected long invoke_J(Object a0, int a1) { return return_J(targetA2(a0, a1)); }
protected float invoke_F(Object a0, int a1) { return return_F(targetA2(a0, a1)); }
protected double invoke_D(Object a0, int a1) { return return_D(targetA2(a0, a1)); }
protected Object invoke_L(int a0, int a1) { return return_L(targetA2(a0, a1)); }
protected int invoke_I(int a0, int a1) { return return_I(targetA2(a0, a1)); }
protected long invoke_J(int a0, int a1) { return return_J(targetA2(a0, a1)); }
protected float invoke_F(int a0, int a1) { return return_F(targetA2(a0, a1)); }
protected double invoke_D(int a0, int a1) { return return_D(targetA2(a0, a1)); }
protected Object invoke_L(Object a0, long a1) { return return_L(targetA2(a0, a1)); }
protected int invoke_I(Object a0, long a1) { return return_I(targetA2(a0, a1)); }
protected long invoke_J(Object a0, long a1) { return return_J(targetA2(a0, a1)); }
protected float invoke_F(Object a0, long a1) { return return_F(targetA2(a0, a1)); }
protected double invoke_D(Object a0, long a1) { return return_D(targetA2(a0, a1)); }
protected Object invoke_L(long a0, long a1) { return return_L(targetA2(a0, a1)); }
protected int invoke_I(long a0, long a1) { return return_I(targetA2(a0, a1)); }
protected long invoke_J(long a0, long a1) { return return_J(targetA2(a0, a1)); }
protected float invoke_F(long a0, long a1) { return return_F(targetA2(a0, a1)); }
protected double invoke_D(long a0, long a1) { return return_D(targetA2(a0, a1)); }
protected Object target(Object a0, Object a1) throws Throwable { return invoker.<Object>invoke(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) { return invoker.<Object>invoke(target, a0, a1, a2); }
protected Object targetA3(Object a0, Object a1, Object a2) { return target(a0, a1, a2); }
protected Object targetA3(Object a0, Object a1, int a2) { return target(a0, a1, a2); }
protected Object targetA3(Object a0, int a1, int a2) { return target(a0, a1, a2); }
protected Object targetA3(int a0, int a1, int a2) { return target(a0, a1, a2); }
protected Object targetA3(Object a0, Object a1, long a2) { return target(a0, a1, a2); }
protected Object targetA3(Object a0, long a1, long a2) { return target(a0, a1, a2); }
protected Object targetA3(long a0, long a1, long a2) { return target(a0, a1, a2); }
protected Object invoke_L(Object a0, Object a1, Object a2) { return return_L(targetA3(a0, a1, a2)); }
protected int invoke_I(Object a0, Object a1, Object a2) { return return_I(targetA3(a0, a1, a2)); }
protected long invoke_J(Object a0, Object a1, Object a2) { return return_J(targetA3(a0, a1, a2)); }
protected float invoke_F(Object a0, Object a1, Object a2) { return return_F(targetA3(a0, a1, a2)); }
protected double invoke_D(Object a0, Object a1, Object a2) { return return_D(targetA3(a0, a1, a2)); }
protected Object invoke_L(Object a0, Object a1, int a2) { return return_L(targetA3(a0, a1, a2)); }
protected int invoke_I(Object a0, Object a1, int a2) { return return_I(targetA3(a0, a1, a2)); }
protected long invoke_J(Object a0, Object a1, int a2) { return return_J(targetA3(a0, a1, a2)); }
protected float invoke_F(Object a0, Object a1, int a2) { return return_F(targetA3(a0, a1, a2)); }
protected double invoke_D(Object a0, Object a1, int a2) { return return_D(targetA3(a0, a1, a2)); }
protected Object invoke_L(Object a0, int a1, int a2) { return return_L(targetA3(a0, a1, a2)); }
protected int invoke_I(Object a0, int a1, int a2) { return return_I(targetA3(a0, a1, a2)); }
protected long invoke_J(Object a0, int a1, int a2) { return return_J(targetA3(a0, a1, a2)); }
protected float invoke_F(Object a0, int a1, int a2) { return return_F(targetA3(a0, a1, a2)); }
protected double invoke_D(Object a0, int a1, int a2) { return return_D(targetA3(a0, a1, a2)); }
protected Object invoke_L(int a0, int a1, int a2) { return return_L(targetA3(a0, a1, a2)); }
protected int invoke_I(int a0, int a1, int a2) { return return_I(targetA3(a0, a1, a2)); }
protected long invoke_J(int a0, int a1, int a2) { return return_J(targetA3(a0, a1, a2)); }
protected float invoke_F(int a0, int a1, int a2) { return return_F(targetA3(a0, a1, a2)); }
protected double invoke_D(int a0, int a1, int a2) { return return_D(targetA3(a0, a1, a2)); }
protected Object invoke_L(Object a0, Object a1, long a2) { return return_L(targetA3(a0, a1, a2)); }
protected int invoke_I(Object a0, Object a1, long a2) { return return_I(targetA3(a0, a1, a2)); }
protected long invoke_J(Object a0, Object a1, long a2) { return return_J(targetA3(a0, a1, a2)); }
protected float invoke_F(Object a0, Object a1, long a2) { return return_F(targetA3(a0, a1, a2)); }
protected double invoke_D(Object a0, Object a1, long a2) { return return_D(targetA3(a0, a1, a2)); }
protected Object invoke_L(Object a0, long a1, long a2) { return return_L(targetA3(a0, a1, a2)); }
protected int invoke_I(Object a0, long a1, long a2) { return return_I(targetA3(a0, a1, a2)); }
protected long invoke_J(Object a0, long a1, long a2) { return return_J(targetA3(a0, a1, a2)); }
protected float invoke_F(Object a0, long a1, long a2) { return return_F(targetA3(a0, a1, a2)); }
protected double invoke_D(Object a0, long a1, long a2) { return return_D(targetA3(a0, a1, a2)); }
protected Object invoke_L(long a0, long a1, long a2) { return return_L(targetA3(a0, a1, a2)); }
protected int invoke_I(long a0, long a1, long a2) { return return_I(targetA3(a0, a1, a2)); }
protected long invoke_J(long a0, long a1, long a2) { return return_J(targetA3(a0, a1, a2)); }
protected float invoke_F(long a0, long a1, long a2) { return return_F(targetA3(a0, a1, a2)); }
protected double invoke_D(long a0, long a1, long a2) { return return_D(targetA3(a0, a1, a2)); }
protected Object target(Object a0, Object a1, Object a2) throws Throwable { return invoker.<Object>invoke(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, 5, 2, 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) { return invoker.<Object>invoke(target, a0, a1, a2, a3); }
protected Object targetA4(Object a0, Object a1, Object a2, Object a3) { return target(a0, a1, a2, a3); }
protected Object targetA4(Object a0, Object a1, Object a2, int a3) { return target(a0, a1, a2, a3); }
protected Object targetA4(Object a0, Object a1, int a2, int a3) { return target(a0, a1, a2, a3); }
protected Object targetA4(Object a0, int a1, int a2, int a3) { return target(a0, a1, a2, a3); }
protected Object targetA4(int a0, int a1, int a2, int a3) { return target(a0, a1, a2, a3); }
protected Object targetA4(Object a0, Object a1, Object a2, long a3) { return target(a0, a1, a2, a3); }
protected Object targetA4(Object a0, Object a1, long a2, long a3) { return target(a0, a1, a2, a3); }
protected Object targetA4(Object a0, long a1, long a2, long a3) { return target(a0, a1, a2, a3); }
protected Object targetA4(long a0, long a1, long a2, long a3) { return target(a0, a1, a2, a3); }
protected Object invoke_L(Object a0, Object a1, Object a2, Object a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, Object a2, Object a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, Object a2, Object a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, Object a1, Object a2, int a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, Object a2, int a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, Object a2, int a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, Object a1, int a2, int a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, int a2, int a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, int a2, int a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, int a1, int a2, int a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, int a1, int a2, int a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, int a1, int a2, int a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(int a0, int a1, int a2, int a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(int a0, int a1, int a2, int a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(int a0, int a1, int a2, int a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, Object a1, Object a2, long a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, Object a2, long a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, Object a2, long a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, Object a1, long a2, long a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, Object a1, long a2, long a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, Object a1, long a2, long a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(Object a0, long a1, long a2, long a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(Object a0, long a1, long a2, long a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(Object a0, long a1, long a2, long a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object invoke_L(long a0, long a1, long a2, long a3) { return return_L(targetA4(a0, a1, a2, a3)); }
protected int invoke_I(long a0, long a1, long a2, long a3) { return return_I(targetA4(a0, a1, a2, a3)); }
protected long invoke_J(long a0, long a1, long a2, long a3) { return return_J(targetA4(a0, a1, a2, a3)); }
protected Object target(Object a0, Object a1, Object a2, Object a3) throws Throwable { return invoker.<Object>invoke(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 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 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 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 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 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 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 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 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)); }
}
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) { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, Object a1, Object a2, Object a3, Object a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, Object a1, Object a2, Object a3, int a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, Object a1, Object a2, int a3, int a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, Object a1, int a2, int a3, int a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, int a1, int a2, int a3, int a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(int a0, int a1, int a2, int a3, int a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, Object a1, Object a2, Object a3, long a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, Object a1, Object a2, long a3, long a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, Object a1, long a2, long a3, long a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(Object a0, long a1, long a2, long a3, long a4) { return target(a0, a1, a2, a3, a4); }
protected Object targetA5(long a0, long a1, long a2, long a3, long a4) { return target(a0, a1, a2, a3, a4); }
protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, Object a1, Object a2, Object a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, Object a1, Object a2, Object a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(Object a0, Object a1, Object a2, int a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, Object a1, Object a2, int a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, Object a1, Object a2, int a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(Object a0, Object a1, int a2, int a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, Object a1, int a2, int a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, Object a1, int a2, int a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(Object a0, int a1, int a2, int a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, int a1, int a2, int a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, int a1, int a2, int a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(int a0, int a1, int a2, int a3, int a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(int a0, int a1, int a2, int a3, int a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(int a0, int a1, int a2, int a3, int a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, Object a1, Object a2, Object a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, Object a1, Object a2, Object a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(Object a0, Object a1, Object a2, long a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, Object a1, Object a2, long a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, Object a1, Object a2, long a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(Object a0, Object a1, long a2, long a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, Object a1, long a2, long a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, Object a1, long a2, long a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(Object a0, long a1, long a2, long a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(Object a0, long a1, long a2, long a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(Object a0, long a1, long a2, long a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object invoke_L(long a0, long a1, long a2, long a3, long a4) { return return_L(targetA5(a0, a1, a2, a3, a4)); }
protected int invoke_I(long a0, long a1, long a2, long a3, long a4) { return return_I(targetA5(a0, a1, a2, a3, a4)); }
protected long invoke_J(long a0, long a1, long a2, long a3, long a4) { return return_J(targetA5(a0, a1, a2, a3, a4)); }
protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return invoker.<Object>invoke(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) { return invoker.<Object>invoke(target, a0, a1, a2, a3, a4, a5); }
protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { return target(a0, a1, a2, a3, a4, a5); }
protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
protected Object targetA6(Object a0, Object a1, Object a2, Object a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
protected Object targetA6(Object a0, Object a1, Object a2, long a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
protected Object targetA6(Object a0, Object a1, long a2, long a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
protected Object targetA6(Object a0, long a1, long a2, long a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
protected Object targetA6(long a0, long a1, long a2, long a3, long a4, long a5) { return target(a0, a1, a2, a3, a4, a5); }
protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return invoker.<Object>invoke(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) { return invoker.<Object>invoke(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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return invoker.<Object>invoke(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) { return invoker.<Object>invoke(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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return invoker.<Object>invoke(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) { return invoker.<Object>invoke(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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
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.<Object>invoke(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) { return invoker.<Object>invoke(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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
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.<Object>invoke(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)); }
}
}
......@@ -29,6 +29,10 @@ package sun.dyn.empty;
* An empty class in an empty package.
* Used as a proxy for unprivileged code, since making access checks
* against it will only succeed against public methods in public types.
* <p>
* This class also stands (internally to sun.dyn) for the type of a
* value that cannot be produced, because the expression of this type
* always returns abnormally. (Cf. Nothing in the closures proposal.)
* @author jrose
*/
public class Empty {
......
......@@ -33,9 +33,9 @@ import java.util.List;
* Utility routines for dealing with bytecode-level signatures.
* @author jrose
*/
public class BytecodeSignature {
public class BytecodeDescriptor {
private BytecodeSignature() { } // cannot instantiate
private BytecodeDescriptor() { } // cannot instantiate
public static List<Class<?>> parseMethod(String bytecodeSignature, ClassLoader loader) {
return parseMethod(bytecodeSignature, 0, bytecodeSignature.length(), loader);
......
......@@ -298,6 +298,8 @@ public class BytecodeName {
* The name {@code &lt;init&gt;} will be parsed into { '&lt;', "init", '&gt;'}}
* The name {@code foo/bar$:baz} will be parsed into
* {@code {"foo", '/', "bar", '$', ':', "baz"}}.
* The name {@code ::\=:foo:\=bar\!baz} will be parsed into
* {@code {':', ':', "", ':', "foo", ':', "bar:baz"}}.
*/
public static Object[] parseBytecodeName(String s) {
int slen = s.length();
......@@ -315,7 +317,7 @@ public class BytecodeName {
if (lasti < i) {
// normal component
if (pass != 0)
res[fillp] = s.substring(lasti, i);
res[fillp] = toSourceName(s.substring(lasti, i));
fillp++;
lasti = i+1;
}
......@@ -323,13 +325,14 @@ public class BytecodeName {
if (pass != 0)
res[fillp] = DANGEROUS_CHARS_CA[whichDC];
fillp++;
lasti = i+1;
}
}
if (pass != 0) break;
// between passes, build the result array
res = new String[fillp];
if (fillp <= 1) {
if (fillp != 0) res[0] = s;
res = new Object[fillp];
if (fillp <= 1 && lasti == 0) {
if (fillp != 0) res[0] = toSourceName(s);
break;
}
}
......@@ -348,9 +351,19 @@ public class BytecodeName {
* @throws NullPointerException if any component is null
*/
public static String unparseBytecodeName(Object[] components) {
for (Object c : components) {
if (c instanceof String)
checkSafeBytecodeName((String) c); // may fail
Object[] components0 = components;
for (int i = 0; i < components.length; i++) {
Object c = components[i];
if (c instanceof String) {
String mc = toBytecodeName((String) c);
if (i == 0 && components.length == 1)
return mc; // usual case
if ((Object)mc != c) {
if (components == components0)
components = components.clone();
components[i] = c = mc;
}
}
}
return appendAll(components);
}
......@@ -381,6 +394,14 @@ public class BytecodeName {
* If the bytecode name contains dangerous characters,
* assume that they are being used as punctuation,
* and pass them through unchanged.
* Non-empty runs of non-dangerous characters are demangled
* if necessary, and the resulting names are quoted if
* they are not already valid Java identifiers, or if
* they contain a dangerous character (i.e., dollar sign "$").
* Single quotes are used when quoting.
* Within quoted names, embedded single quotes and backslashes
* are further escaped by prepended backslashes.
*
* @param s the original bytecode name (which may be qualified)
* @return a human-readable presentation
*/
......@@ -389,10 +410,10 @@ public class BytecodeName {
for (int i = 0; i < components.length; i++) {
if (!(components[i] instanceof String))
continue;
String c = (String) components[i];
// pretty up the name by demangling it
String sn = toSourceName(c);
if ((Object)sn != c || !isJavaIdent(sn)) {
String sn = (String) components[i];
// note that the name is already demangled!
//sn = toSourceName(sn);
if (!isJavaIdent(sn) || sn.indexOf('$') >=0 ) {
components[i] = quoteDisplay(sn);
}
}
......@@ -401,10 +422,10 @@ public class BytecodeName {
private static boolean isJavaIdent(String s) {
int slen = s.length();
if (slen == 0) return false;
if (!Character.isUnicodeIdentifierStart(s.charAt(0)))
if (!Character.isJavaIdentifierStart(s.charAt(0)))
return false;
for (int i = 1; i < slen; i++) {
if (!Character.isUnicodeIdentifierPart(s.charAt(0)))
if (!Character.isJavaIdentifierPart(s.charAt(i)))
return false;
}
return true;
......@@ -602,110 +623,5 @@ public class BytecodeName {
return -1;
}
// test driver
static void main(String[] av) {
// If verbose is enabled, quietly check everything.
// Otherwise, print the output for the user to check.
boolean verbose = false;
int maxlen = 0;
while (av.length > 0 && av[0].startsWith("-")) {
String flag = av[0].intern();
av = java.util.Arrays.copyOfRange(av, 1, av.length); // Java 1.6 or later
if (flag == "-" || flag == "--") break;
else if (flag == "-q")
verbose = false;
else if (flag == "-v")
verbose = true;
else if (flag.startsWith("-l"))
maxlen = Integer.valueOf(flag.substring(2));
else
throw new Error("Illegal flag argument: "+flag);
}
if (maxlen == 0)
maxlen = (verbose ? 2 : 4);
if (verbose) System.out.println("Note: maxlen = "+maxlen);
switch (av.length) {
case 0: av = new String[] {
DANGEROUS_CHARS.substring(0) +
REPLACEMENT_CHARS.substring(0, 1) +
NULL_ESCAPE + "x"
}; // and fall through:
case 1:
char[] cv = av[0].toCharArray();
av = new String[cv.length];
int avp = 0;
for (char c : cv) {
String s = String.valueOf(c);
if (c == 'x') s = "foo"; // tradition...
av[avp++] = s;
}
}
if (verbose)
System.out.println("Note: Verbose output mode enabled. Use '-q' to suppress.");
Tester t = new Tester();
t.maxlen = maxlen;
t.verbose = verbose;
t.tokens = av;
t.test("", 0);
}
static class Tester {
boolean verbose;
int maxlen;
java.util.Map<String,String> map = new java.util.HashMap<String,String>();
String[] tokens;
void test(String stringSoFar, int tokensSoFar) {
test(stringSoFar);
if (tokensSoFar <= maxlen) {
for (String token : tokens) {
if (token.length() == 0) continue; // skip empty tokens
if (stringSoFar.indexOf(token) != stringSoFar.lastIndexOf(token))
continue; // there are already two occs. of this token
if (token.charAt(0) == ESCAPE_C && token.length() == 1 && maxlen < 4)
test(stringSoFar+token, tokensSoFar); // want lots of \'s
else if (tokensSoFar < maxlen)
test(stringSoFar+token, tokensSoFar+1);
}
}
}
void test(String s) {
// for small batches, do not test the null string
if (s.length() == 0 && maxlen >=1 && maxlen <= 2) return;
String bn = testSourceName(s);
if (bn == null) return;
if (bn == s) {
//if (verbose) System.out.println(s+" == id");
} else {
if (verbose) System.out.println(s+" => "+bn+" "+toDisplayName(bn));
String bnbn = testSourceName(bn);
if (bnbn == null) return;
if (verbose) System.out.println(bn+" => "+bnbn+" "+toDisplayName(bnbn));
/*
String bn3 = testSourceName(bnbn);
if (bn3 == null) return;
if (verbose) System.out.println(bnbn+" => "+bn3);
*/
}
}
String testSourceName(String s) {
if (map.containsKey(s)) return null;
String bn = toBytecodeName(s);
map.put(s, bn);
String sn = toSourceName(bn);
if (!sn.equals(s)) {
String bad = (s+" => "+bn+" != "+sn);
if (!verbose) throw new Error("Bad mangling: "+bad);
System.out.println("*** "+bad);
return null;
}
return bn;
}
}
}
......@@ -27,7 +27,10 @@ package sun.dyn.util;
import java.dyn.*;
import java.dyn.MethodHandles.Lookup;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
import sun.dyn.Access;
import sun.dyn.AdapterMethodHandle;
import sun.dyn.MethodHandleImpl;
......@@ -37,6 +40,7 @@ public class ValueConversions {
private static final Lookup IMPL_LOOKUP = MethodHandleImpl.getLookup(IMPL_TOKEN);
private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
@SuppressWarnings("unchecked")
EnumMap<Wrapper, MethodHandle>[] caches
= (EnumMap<Wrapper, MethodHandle>[]) new EnumMap[n]; // unchecked warning expected here
for (int i = 0; i < n; i++)
......@@ -114,7 +118,7 @@ public class ValueConversions {
}
private static MethodType unboxType(Wrapper wrap, boolean raw) {
return MethodType.make(rawWrapper(wrap, raw).primitiveType(), wrap.wrapperType());
return MethodType.methodType(rawWrapper(wrap, raw).primitiveType(), wrap.wrapperType());
}
private static final EnumMap<Wrapper, MethodHandle>[]
......@@ -240,7 +244,7 @@ public class ValueConversions {
private static MethodType boxType(Wrapper wrap, boolean raw) {
// be exact, since return casts are hard to compose
Class<?> boxType = wrap.wrapperType();
return MethodType.make(boxType, rawWrapper(wrap, raw).primitiveType());
return MethodType.methodType(boxType, rawWrapper(wrap, raw).primitiveType());
}
private static Wrapper rawWrapper(Wrapper wrap, boolean raw) {
......@@ -305,29 +309,47 @@ public class ValueConversions {
/// Kludges for when raw values get accidentally boxed.
static int unboxRawInteger(Object x) {
if (x instanceof Integer)
return unboxInteger(x);
else
return (int) unboxLong(x);
}
static Integer reboxRawInteger(Object x) {
if (x instanceof Integer)
return (Integer) x;
else
return (int) unboxLong(x);
}
static Byte reboxRawByte(Object x) {
if (x instanceof Byte) return (Byte) x;
return boxByteRaw(unboxInteger(x));
return boxByteRaw(unboxRawInteger(x));
}
static Short reboxRawShort(Object x) {
if (x instanceof Short) return (Short) x;
return boxShortRaw(unboxInteger(x));
return boxShortRaw(unboxRawInteger(x));
}
static Boolean reboxRawBoolean(Object x) {
if (x instanceof Boolean) return (Boolean) x;
return boxBooleanRaw(unboxInteger(x));
return boxBooleanRaw(unboxRawInteger(x));
}
static Character reboxRawCharacter(Object x) {
if (x instanceof Character) return (Character) x;
return boxCharacterRaw(unboxInteger(x));
return boxCharacterRaw(unboxRawInteger(x));
}
static Float reboxRawFloat(Object x) {
if (x instanceof Float) return (Float) x;
return boxFloatRaw(unboxInteger(x));
return boxFloatRaw(unboxRawInteger(x));
}
static Long reboxRawLong(Object x) {
return (Long) x; //never a rebox
}
static Double reboxRawDouble(Object x) {
......@@ -337,12 +359,21 @@ public class ValueConversions {
private static MethodType reboxType(Wrapper wrap) {
Class<?> boxType = wrap.wrapperType();
return MethodType.make(boxType, Object.class);
return MethodType.methodType(boxType, Object.class);
}
private static final EnumMap<Wrapper, MethodHandle>[]
REBOX_CONVERSIONS = newWrapperCaches(2);
/**
* Becase we normalize primitive types to reduce the number of signatures,
* primitives are sometimes manipulated under an "erased" type,
* either int (for types other than long/double) or long (for all types).
* When the erased primitive value is then boxed into an Integer or Long,
* the final boxed primitive is sometimes required. This transformation
* is called a "rebox". It takes an Integer or Long and produces some
* other boxed value.
*/
public static MethodHandle rebox(Wrapper wrap, boolean exact) {
EnumMap<Wrapper, MethodHandle> cache = REBOX_CONVERSIONS[exact?1:0];
MethodHandle mh = cache.get(wrap);
......@@ -355,9 +386,6 @@ public class ValueConversions {
mh = IDENTITY; break;
case VOID:
throw new IllegalArgumentException("cannot rebox a void");
case INT: case LONG:
mh = cast(wrap.wrapperType(), exact);
break;
}
if (mh != null) {
cache.put(wrap, mh);
......@@ -384,13 +412,21 @@ public class ValueConversions {
/// Width-changing conversions between int and long.
static long widenInt(int x) {
return x;
return (long) x;
}
static Long widenBoxedInt(Integer x) {
return (long)(int)x;
}
static int narrowLong(long x) {
return (int) x;
}
static Integer narrowBoxedLong(Long x) {
return (int)(long) x;
}
/// Constant functions
static void ignore(Object x) {
......@@ -432,7 +468,7 @@ public class ValueConversions {
return mh;
}
// slow path
MethodType type = MethodType.make(wrap.primitiveType());
MethodType type = MethodType.methodType(wrap.primitiveType());
switch (wrap) {
case VOID:
mh = EMPTY;
......@@ -500,11 +536,11 @@ public class ValueConversions {
private static final MethodHandle IDENTITY, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY;
static {
try {
MethodType idType = MethodType.makeGeneric(1);
MethodType castType = idType.insertParameterType(0, Class.class);
MethodType idType = MethodType.genericMethodType(1);
MethodType castType = idType.insertParameterTypes(0, Class.class);
MethodType alwaysZeroType = idType.changeReturnType(int.class);
MethodType ignoreType = idType.changeReturnType(void.class);
MethodType zeroObjectType = MethodType.makeGeneric(0);
MethodType zeroObjectType = MethodType.genericMethodType(0);
IDENTITY = IMPL_LOOKUP.findStatic(ValueConversions.class, "identity", idType);
//CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
CAST_REFERENCE = IMPL_LOOKUP.findStatic(ValueConversions.class, "castReference", castType);
......@@ -512,7 +548,7 @@ public class ValueConversions {
ALWAYS_ZERO = IMPL_LOOKUP.findStatic(ValueConversions.class, "alwaysZero", alwaysZeroType);
ZERO_OBJECT = IMPL_LOOKUP.findStatic(ValueConversions.class, "zeroObject", zeroObjectType);
IGNORE = IMPL_LOOKUP.findStatic(ValueConversions.class, "ignore", ignoreType);
EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterType(0));
EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterTypes(0, 1));
} catch (RuntimeException ex) {
throw ex;
}
......@@ -543,10 +579,10 @@ public class ValueConversions {
else if (VerifyType.isNullType(type))
mh = ALWAYS_NULL;
else
mh = MethodHandles.insertArgument(CAST_REFERENCE, 0, type);
mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
if (exact) {
MethodType xmt = MethodType.make(type, Object.class);
mh = AdapterMethodHandle.makeRawRetypeOnly(IMPL_TOKEN, xmt, mh);
MethodType xmt = MethodType.methodType(type, Object.class);
mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh);
}
if (cache != null)
cache.put(wrap, mh);
......@@ -560,4 +596,127 @@ public class ValueConversions {
private static MethodHandle retype(MethodType type, MethodHandle mh) {
return AdapterMethodHandle.makeRetypeOnly(IMPL_TOKEN, type, mh);
}
private static final Object[] NO_ARGS_ARRAY = {};
private static Object[] makeArray(Object... args) { return args; }
private static Object[] array() { return NO_ARGS_ARRAY; }
private static Object[] array(Object a0)
{ return makeArray(a0); }
private static Object[] array(Object a0, Object a1)
{ return makeArray(a0, a1); }
private static Object[] array(Object a0, Object a1, Object a2)
{ return makeArray(a0, a1, a2); }
private static Object[] array(Object a0, Object a1, Object a2, Object a3)
{ return makeArray(a0, a1, a2, a3); }
private static Object[] array(Object a0, Object a1, Object a2, Object a3,
Object a4)
{ return makeArray(a0, a1, a2, a3, a4); }
private static Object[] array(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5)
{ return makeArray(a0, a1, a2, a3, a4, a5); }
private static Object[] array(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6)
{ return makeArray(a0, a1, a2, a3, a4, a5, a6); }
private static Object[] array(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7)
{ return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
private static Object[] array(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8)
{ return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
private static Object[] array(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8, Object a9)
{ return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
static MethodHandle[] makeArrays() {
ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
MethodHandles.Lookup lookup = IMPL_LOOKUP;
for (;;) {
int nargs = arrays.size();
MethodType type = MethodType.genericMethodType(nargs).changeReturnType(Object[].class);
String name = "array";
MethodHandle array = null;
try {
array = lookup.findStatic(ValueConversions.class, name, type);
} catch (NoAccessException ex) {
}
if (array == null) break;
arrays.add(array);
}
assert(arrays.size() == 11); // current number of methods
return arrays.toArray(new MethodHandle[0]);
}
static final MethodHandle[] ARRAYS = makeArrays();
/** Return a method handle that takes the indicated number of Object
* arguments and returns an Object array of them, as if for varargs.
*/
public static MethodHandle varargsArray(int nargs) {
if (nargs < ARRAYS.length)
return ARRAYS[nargs];
// else need to spin bytecode or do something else fancy
throw new UnsupportedOperationException("NYI");
}
private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
private static List<Object> list() { return NO_ARGS_LIST; }
private static List<Object> list(Object a0)
{ return makeList(a0); }
private static List<Object> list(Object a0, Object a1)
{ return makeList(a0, a1); }
private static List<Object> list(Object a0, Object a1, Object a2)
{ return makeList(a0, a1, a2); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
{ return makeList(a0, a1, a2, a3); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4)
{ return makeList(a0, a1, a2, a3, a4); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5)
{ return makeList(a0, a1, a2, a3, a4, a5); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6)
{ return makeList(a0, a1, a2, a3, a4, a5, a6); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7)
{ return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8)
{ return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8, Object a9)
{ return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
static MethodHandle[] makeLists() {
ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
MethodHandles.Lookup lookup = IMPL_LOOKUP;
for (;;) {
int nargs = arrays.size();
MethodType type = MethodType.genericMethodType(nargs).changeReturnType(List.class);
String name = "list";
MethodHandle array = null;
try {
array = lookup.findStatic(ValueConversions.class, name, type);
} catch (NoAccessException ex) {
}
if (array == null) break;
arrays.add(array);
}
assert(arrays.size() == 11); // current number of methods
return arrays.toArray(new MethodHandle[0]);
}
static final MethodHandle[] LISTS = makeLists();
/** Return a method handle that takes the indicated number of Object
* arguments and returns List.
*/
public static MethodHandle varargsList(int nargs) {
if (nargs < LISTS.length)
return LISTS[nargs];
// else need to spin bytecode or do something else fancy
throw new UnsupportedOperationException("NYI");
}
}
......@@ -26,8 +26,12 @@
package sun.dyn.util;
import java.dyn.LinkagePermission;
import java.dyn.MethodHandles.Lookup;
import java.dyn.NoAccessException;
import java.lang.reflect.Modifier;
import sun.dyn.Access;
import sun.dyn.MemberName;
import sun.dyn.MethodHandleImpl;
import sun.dyn.empty.Empty;
/**
* This class centralizes information about the JVM's linkage access control.
......@@ -45,21 +49,21 @@ public class VerifyAccess {
* <p>
* Some circumstances require an additional check on the
* leading parameter (the receiver) of the method, if it is non-static.
* In the case of {@code invokespecial} ({@code doDispatch} is false),
* In the case of {@code invokespecial} ({@code isSpecialInvoke} is true),
* the leading parameter must be the accessing class or a subclass.
* In the case of a call to a {@code protected} method outside the same
* package, the same constraint applies.
* @param m the proposed callee
* @param doDispatch if false, a non-static m will be invoked as if by {@code invokespecial}
* @param isSpecialInvoke if true, a non-static method m is checked as if for {@code invokespecial}
* @param lookupClass the class for which the access check is being made
* @return null if the method is not accessible, else a receiver type constraint, else {@code Object.class}
*/
public static Class<?> isAccessible(Class<?> defc, int mods,
boolean doDispatch, Class<?> lookupClass) {
Class<?> lookupClass, boolean isSpecialInvoke) {
if (!isAccessible(defc, lookupClass))
return null;
Class<?> constraint = Object.class;
if (!doDispatch && !Modifier.isStatic(mods)) {
if (isSpecialInvoke && !Modifier.isStatic(mods)) {
constraint = lookupClass;
}
if (Modifier.isPublic(mods))
......@@ -166,4 +170,38 @@ public class VerifyAccess {
if (isSamePackage(requestingClass, subjectClass)) return;
security.checkPermission(new LinkagePermission(permissionName, requestingClass));
}
private static RuntimeException checkNameFailed(MemberName self, Lookup lookup, String comment) {
return new NoAccessException("cannot access from "+lookup+": "+self.toString()+": "+comment);
}
public static void checkName(MemberName self, Lookup lookup) {
Class<?> lc = lookup.lookupClass();
if (lc == null) return; // lookup is privileged
Class<?> dc = self.getDeclaringClass();
int samepkg = 0;
// First check the containing class. Must be public or local.
if (!Modifier.isPublic(dc.getModifiers())) {
if (lc != Empty.class)
samepkg = (isSamePackage(dc, lc) ? 1 : -1);
if (samepkg <= 0)
throw checkNameFailed(self, lookup, "class is not public");
}
// At this point dc is known to be accessible.
if (self.isPublic()) {
return;
} else if (lc == Empty.class) {
throw checkNameFailed(self, lookup, "member is not public");
} else if (self.isProtected()) {
if (dc.isAssignableFrom(lc)) return;
} else if (self.isPrivate()) {
if (isSamePackageMember(dc, lc)) return;
throw checkNameFailed(self, lookup, "member is private");
}
// Fall-through handles the package-private and protected cases.
if (samepkg == 0)
samepkg = (isSamePackage(dc, lc) ? 1 : -1);
if (samepkg > 0) return;
throw checkNameFailed(self, lookup,
self.isProtected() ? "member is protected" : "member is private to package");
}
}
......@@ -26,6 +26,7 @@
package sun.dyn.util;
import java.dyn.MethodType;
import sun.dyn.empty.Empty;
/**
* This class centralizes information about the JVM verifier
......@@ -73,29 +74,28 @@ public class VerifyType {
}
/**
* Is the given type either java.lang.Void or java.lang.Null?
* These types serve as markers for bare nulls and therefore
* may be promoted to any type. This is secure, since
* Is the given type java.lang.Null or an equivalent null-only type?
*/
public static boolean isNullType(Class<?> type) {
if (type == null) return false;
return type == NULL_CLASS_1 || type == NULL_CLASS_2;
return type == NULL_CLASS
// This one may also be used as a null type.
// TO DO: Decide if we really want to legitimize it here.
// Probably we do, unless java.lang.Null really makes it into Java 7
//|| type == Void.class
// Locally known null-only class:
|| type == Empty.class
;
}
private static final Class<?> NULL_CLASS_1, NULL_CLASS_2;
private static final Class<?> NULL_CLASS;
static {
Class<?> nullClass1 = null, nullClass2 = null;
Class<?> nullClass = null;
try {
nullClass1 = Class.forName("java.lang.Null");
nullClass = Class.forName("java.lang.Null");
} catch (ClassNotFoundException ex) {
// OK, we'll cope
}
NULL_CLASS_1 = nullClass1;
// This one may also be used as a null type.
// TO DO: Decide if we really want to legitimize it here.
// Probably we do, unless java.lang.Null really makes it into Java 7
nullClass2 = Void.class;
NULL_CLASS_2 = nullClass2;
NULL_CLASS = nullClass;
}
/**
......@@ -191,6 +191,11 @@ public class VerifyType {
// to be captured as a garbage int.
// Caller promises that the actual value will be disregarded.
return dst == int.class ? 1 : 0;
if (isNullType(src))
// Special permission for raw conversions: allow a null
// to be reinterpreted as anything. For objects, it is safe,
// and for primitives you get a garbage value (probably zero).
return 1;
if (!src.isPrimitive())
return 0;
Wrapper sw = Wrapper.forPrimitiveType(src);
......
......@@ -141,13 +141,19 @@ public enum Wrapper {
* @throws IllegalArgumentException for unexpected types
*/
public static Wrapper forPrimitiveType(Class<?> type) {
Wrapper w = findPrimitiveType(type);
if (w != null) return w;
if (type.isPrimitive())
throw new InternalError(); // redo hash function
throw newIllegalArgumentException("not primitive: "+type);
}
static Wrapper findPrimitiveType(Class<?> type) {
Wrapper w = FROM_PRIM[hashPrim(type)];
if (w != null && w.primitiveType == type) {
return w;
}
if (type.isPrimitive())
throw new InternalError(); // redo hash function
throw newIllegalArgumentException("not primitive: "+type);
return null;
}
/** Return the wrapper that wraps values into the given wrapper type.
......@@ -160,7 +166,7 @@ public enum Wrapper {
Wrapper w = findWrapperType(type);
if (w != null) return w;
for (Wrapper x : values())
if (w.wrapperType == type)
if (x.wrapperType == type)
throw new InternalError(); // redo hash function
throw newIllegalArgumentException("not wrapper: "+type);
}
......@@ -244,8 +250,10 @@ public enum Wrapper {
public Class<?> wrapperType() { return wrapperType; }
/** What is the wrapper type for this wrapper?
* The example type must be the wrapper type,
* Otherwise, the example type must be the wrapper type,
* or the corresponding primitive type.
* (For {@code OBJECT}, the example type can be any non-primitive,
* and is normalized to {@code Object.class}.)
* The resulting class type has the same type parameter.
*/
public <T> Class<T> wrapperType(Class<T> exampleType) {
......@@ -290,6 +298,16 @@ public enum Wrapper {
return type.isPrimitive();
}
/** What is the bytecode signature character for this type?
* All non-primitives, including array types, report as 'L', the signature character for references.
*/
public static char basicTypeChar(Class<?> type) {
if (!type.isPrimitive())
return 'L';
else
return forPrimitiveType(type).basicTypeChar();
}
/** What is the bytecode signature character for this wrapper's
* primitive type?
*/
......@@ -309,7 +327,7 @@ public enum Wrapper {
/** Cast a wrapped value to the given type, which may be either a primitive or wrapper type.
* Performs standard primitive conversions, including truncation and float conversions.
* The given type must be compatible with this wrapper. That is, it must either
* be the wrapper type (or a subtype, in the case of {@code OBJECT} or else
* be the wrapper type (or a subtype, in the case of {@code OBJECT}) or else
* it must be the wrapper's primitive type.
* @throws ClassCastException if the given type is not compatible with this wrapper
*/
......@@ -326,9 +344,17 @@ public enum Wrapper {
* If the target type is a primitive, change it to a wrapper.
*/
static <T> Class<T> forceType(Class<?> type, Class<T> exampleType) {
boolean z = (type == exampleType ||
type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
type == Object.class && !exampleType.isPrimitive());
if (!z)
System.out.println(type+" <= "+exampleType);
assert(type == exampleType ||
type == asWrapperType(exampleType) ||
type == Object.class && exampleType.isInterface());
type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
type == Object.class && !exampleType.isPrimitive());
@SuppressWarnings("unchecked")
Class<T> result = (Class<T>) type; // unchecked warning is expected here
return result;
}
......
......@@ -35,9 +35,10 @@ import java.dyn.*;
import java.dyn.MethodHandles.Lookup;
import java.lang.reflect.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.*;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;
/**
......@@ -66,28 +67,37 @@ public class MethodHandlesTest {
} finally { verbosity -= 9; }
}
// current failures
@Test @Ignore("failure in call to makeRawRetypeOnly in ToGeneric")
public void testFail_1() throws Throwable {
testSpreadArguments(int.class, 0, 6);
}
@Test @Ignore("failure in JVM when expanding the stack")
public void testFail_2() throws Throwable {
// if CONV_OP_IMPLEMENTED_MASK includes OP_SPREAD_ARGS, this crashes:
testSpreadArguments(Object.class, 0, 2);
}
@Test @Ignore("IllArgEx failure in call to ToGeneric.make")
public void testFail_3() throws Throwable {
testSpreadArguments(int.class, 1, 2);
}
@Test @Ignore("IllArgEx failure in call to ToGeneric.make")
public void testFail_4() throws Throwable {
testCollectArguments(int.class, 1, 2);
}
@Test @Ignore("cannot collect leading primitive types")
public void testFail_5() throws Throwable {
testInvokers(MethodType.genericMethodType(2).changeParameterType(0, int.class));
}
@Test @Ignore("should not insert arguments beyond MethodHandlePushLimit")
public void testFail_6() throws Throwable {
testInsertArguments(0, 0, MAX_ARG_INCREASE+1);
}
static final int MAX_ARG_INCREASE = 3;
public MethodHandlesTest() {
}
@Before
public void checkImplementedPlatform() {
boolean platformOK = false;
Properties properties = System.getProperties();
String vers = properties.getProperty("java.vm.version");
String name = properties.getProperty("java.vm.name");
String arch = properties.getProperty("os.arch");
if (arch.equals("i386") &&
(name.contains("Client") || name.contains("Server"))
) {
platformOK = true;
} else {
System.err.println("Skipping tests for unsupported platform: "+Arrays.asList(vers, name, arch));
}
assumeTrue(platformOK);
}
String testName;
int posTests, negTests;
@After
......@@ -171,6 +181,10 @@ public class MethodHandlesTest {
return (float)(value);
if (dst == double.class || dst == Double.class)
return (double)(value);
if (dst == byte.class || dst == Byte.class)
return (byte)(value);
if (dst == boolean.class || dst == boolean.class)
return ((value % 29) & 1) == 0;
return null;
}
......@@ -249,7 +263,7 @@ public class MethodHandlesTest {
end = Math.min(end, targetType.parameterCount());
ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>(targetType.parameterList());
Collections.fill(argTypes.subList(beg, end), argType);
MethodType ttype2 = MethodType.make(targetType.returnType(), argTypes);
MethodType ttype2 = MethodType.methodType(targetType.returnType(), argTypes);
return MethodHandles.convertArguments(target, ttype2);
}
......@@ -258,7 +272,7 @@ public class MethodHandlesTest {
// This lookup is good for package-private members but not private ones.
static final Lookup PACKAGE = PackageSibling.lookup();
// This lookup is good only for public members.
static final Lookup PUBLIC = MethodHandles.Lookup.PUBLIC_LOOKUP;
static final Lookup PUBLIC = MethodHandles.publicLookup();
// Subject methods...
static class Example implements IntExample {
......@@ -306,11 +320,24 @@ public class MethodHandlesTest {
}
static final Object[][][] ACCESS_CASES = {
{ { true, PRIVATE } } // only one test case at present
{ { false, PUBLIC }, { false, PACKAGE }, { false, PRIVATE } },
{ { false, PUBLIC }, { false, PACKAGE }, { true, PRIVATE } },
{ { false, PUBLIC }, { true, PACKAGE }, { true, PRIVATE } },
{ { true, PUBLIC }, { true, PACKAGE }, { true, PRIVATE } },
};
static Object[][] accessCases(Class<?> defc, String name) {
return ACCESS_CASES[0];
if (name.contains("pri_")) {
return ACCESS_CASES[1]; // PRIVATE only
} else if (name.contains("pkg_")) {
return ACCESS_CASES[2]; // not PUBLIC
} else {
assertTrue(name.indexOf('_') < 0);
boolean pubc = Modifier.isPublic(defc.getModifiers());
if (pubc)
return ACCESS_CASES[3]; // all access levels
return ACCESS_CASES[2]; // PACKAGE but not PUBLIC
}
}
@Test
......@@ -343,7 +370,7 @@ public class MethodHandlesTest {
}
void testFindStatic(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
countTest(positive);
MethodType type = MethodType.make(ret, params);
MethodType type = MethodType.methodType(ret, params);
MethodHandle target = null;
RuntimeException noAccess = null;
try {
......@@ -362,7 +389,7 @@ public class MethodHandlesTest {
if (!DO_MORE_CALLS && lookup != PRIVATE) return;
Object[] args = randomArgs(params);
printCalled(target, name, args);
MethodHandles.invoke(target, args);
target.invokeVarargs(args);
assertCalled(name, args);
System.out.print(':');
}
......@@ -405,7 +432,7 @@ public class MethodHandlesTest {
void testFindVirtual(boolean positive, Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
countTest(positive);
String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo
MethodType type = MethodType.make(ret, params);
MethodType type = MethodType.methodType(ret, params);
MethodHandle target = null;
RuntimeException noAccess = null;
try {
......@@ -420,7 +447,7 @@ public class MethodHandlesTest {
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)defc), params);
MethodType typeWithSelf = MethodType.make(ret, paramsWithSelf);
MethodType typeWithSelf = MethodType.methodType(ret, paramsWithSelf);
MethodType ttype = target.type();
ttype = ttype.changeParameterType(0, defc); // FIXME: test this
assertEquals(typeWithSelf, ttype);
......@@ -429,7 +456,7 @@ public class MethodHandlesTest {
Object[] argsWithSelf = randomArgs(paramsWithSelf);
if (rcvc != defc) argsWithSelf[0] = randomArg(rcvc);
printCalled(target, name, argsWithSelf);
MethodHandles.invoke(target, argsWithSelf);
target.invokeVarargs(argsWithSelf);
assertCalled(name, argsWithSelf);
System.out.print(':');
}
......@@ -451,7 +478,7 @@ public class MethodHandlesTest {
}
void testFindSpecial(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
countTest(positive);
MethodType type = MethodType.make(ret, params);
MethodType type = MethodType.methodType(ret, params);
MethodHandle target = null;
RuntimeException noAccess = null;
try {
......@@ -466,7 +493,7 @@ public class MethodHandlesTest {
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)defc), params);
MethodType typeWithSelf = MethodType.make(ret, paramsWithSelf);
MethodType typeWithSelf = MethodType.methodType(ret, paramsWithSelf);
MethodType ttype = target.type();
ttype = ttype.changeParameterType(0, defc); // FIXME: test this
assertEquals(typeWithSelf, ttype);
......@@ -474,7 +501,7 @@ public class MethodHandlesTest {
if (!DO_MORE_CALLS && lookup != PRIVATE) return;
Object[] args = randomArgs(paramsWithSelf);
printCalled(target, name, args);
MethodHandles.invoke(target, args);
target.invokeVarargs(args);
assertCalled(name, args);
System.out.print(':');
}
......@@ -506,7 +533,7 @@ public class MethodHandlesTest {
void testBind(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
countTest(positive);
String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo
MethodType type = MethodType.make(ret, params);
MethodType type = MethodType.methodType(ret, params);
Object receiver = randomArg(defc);
MethodHandle target = null;
RuntimeException noAccess = null;
......@@ -524,7 +551,7 @@ public class MethodHandlesTest {
assertEquals(type, target.type());
Object[] args = randomArgs(params);
printCalled(target, name, args);
MethodHandles.invoke(target, args);
target.invokeVarargs(args);
Object[] argsWithReceiver = cat(array(Object[].class, receiver), args);
assertCalled(name, argsWithReceiver);
System.out.print(':');
......@@ -562,7 +589,7 @@ public class MethodHandlesTest {
}
void testUnreflect(boolean positive, Lookup lookup, Class<?> defc, boolean isStatic, Class<?> ret, String name, Class<?>... params) throws Throwable {
countTest(positive);
MethodType type = MethodType.make(ret, params);
MethodType type = MethodType.methodType(ret, params);
Method rmethod = null;
MethodHandle target = null;
RuntimeException noAccess = null;
......@@ -587,14 +614,14 @@ public class MethodHandlesTest {
if (!isStatic) {
paramsMaybeWithSelf = cat(array(Class[].class, (Class)defc), params);
}
MethodType typeMaybeWithSelf = MethodType.make(ret, paramsMaybeWithSelf);
MethodType typeMaybeWithSelf = MethodType.methodType(ret, paramsMaybeWithSelf);
MethodType ttype = target.type();
if (!isStatic)
ttype = ttype.changeParameterType(0, defc); // FIXME: test this
assertEquals(typeMaybeWithSelf, ttype);
Object[] argsMaybeWithSelf = randomArgs(paramsMaybeWithSelf);
printCalled(target, name, argsMaybeWithSelf);
MethodHandles.invoke(target, argsMaybeWithSelf);
target.invokeVarargs(argsMaybeWithSelf);
assertCalled(name, argsMaybeWithSelf);
System.out.print(':');
}
......@@ -610,46 +637,238 @@ public class MethodHandlesTest {
fail("The test case is a prototype.");
}
@Test @Ignore("unimplemented")
public static class HasFields {
boolean fZ = false;
byte fB = (byte)'B';
short fS = (short)'S';
char fC = 'C';
int fI = 'I';
long fJ = 'J';
float fF = 'F';
double fD = 'D';
static boolean sZ = true;
static byte sB = 1+(byte)'B';
static short sS = 1+(short)'S';
static char sC = 1+'C';
static int sI = 1+'I';
static long sJ = 1+'J';
static float sF = 1+'F';
static double sD = 1+'D';
Object fL = 'L';
String fR = "R";
static Object sL = 'M';
static String sR = "S";
static final Object[][] CASES;
static {
ArrayList<Object[]> cases = new ArrayList<Object[]>();
Object types[][] = {
{'L',Object.class}, {'R',String.class},
{'I',int.class}, {'J',long.class},
{'F',float.class}, {'D',double.class},
{'Z',boolean.class}, {'B',byte.class},
{'S',short.class}, {'C',char.class},
};
HasFields fields = new HasFields();
for (Object[] t : types) {
for (int kind = 0; kind <= 1; kind++) {
boolean isStatic = (kind != 0);
char btc = (Character)t[0];
String name = (isStatic ? "s" : "f") + btc;
Class<?> type = (Class<?>) t[1];
Object value;
Field field;
try {
field = HasFields.class.getDeclaredField(name);
} catch (Exception ex) {
throw new InternalError("no field HasFields."+name);
}
try {
value = field.get(fields);
} catch (Exception ex) {
throw new InternalError("cannot fetch field HasFields."+name);
}
if (type == float.class) {
float v = 'F';
if (isStatic) v++;
assert(value.equals(v));
}
assert(name.equals(field.getName()));
assert(type.equals(field.getType()));
assert(isStatic == (Modifier.isStatic(field.getModifiers())));
cases.add(new Object[]{ field, value });
}
}
CASES = cases.toArray(new Object[0][]);
}
}
@Test
public void testUnreflectGetter() throws Throwable {
Lookup lookup = PRIVATE; // FIXME: test more lookups than this one
startTest("unreflectGetter");
Field f = null;
MethodHandle expResult = null;
MethodHandle result = lookup.unreflectGetter(f);
assertEquals(expResult, result);
fail("The test case is a prototype.");
for (Object[] c : HasFields.CASES) {
Field f = (Field)c[0];
Object value = c[1];
Class<?> type = f.getType();
if (type.isPrimitive() && type != int.class)
continue; //FIXME
testUnreflectGetter(lookup, f, type, value);
}
}
public void testUnreflectGetter(MethodHandles.Lookup lookup,
Field f, Class<?> type, Object value) throws Throwable {
countTest(true);
boolean isStatic = Modifier.isStatic(f.getModifiers());
MethodType expType = MethodType.methodType(type, HasFields.class);
if (isStatic) expType = expType.dropParameterTypes(0, 1);
MethodHandle mh = lookup.unreflectGetter(f);
assertSame(mh.type(), expType);
assertEquals(mh.toString(), f.getName());
HasFields fields = new HasFields();
Object sawValue;
Class<?> rtype = type;
if (type != int.class) rtype = Object.class;
mh = MethodHandles.convertArguments(mh, mh.type().generic().changeReturnType(rtype));
Object expValue = value;
for (int i = 0; i <= 1; i++) {
if (isStatic) {
if (type == int.class)
sawValue = mh.<int>invoke(); // do these exactly
else
sawValue = mh.invoke();
} else {
if (type == int.class)
sawValue = mh.<int>invoke((Object) fields);
else
sawValue = mh.invoke((Object) fields);
}
assertEquals(sawValue, expValue);
Object random = randomArg(type);
f.set(fields, random);
expValue = random;
}
f.set(fields, value); // put it back
}
@Test @Ignore("unimplemented")
@Test
public void testUnreflectSetter() throws Throwable {
Lookup lookup = PRIVATE; // FIXME: test more lookups than this one
startTest("unreflectSetter");
Field f = null;
MethodHandle expResult = null;
MethodHandle result = lookup.unreflectSetter(f);
assertEquals(expResult, result);
fail("The test case is a prototype.");
for (Object[] c : HasFields.CASES) {
Field f = (Field)c[0];
Object value = c[1];
Class<?> type = f.getType();
if (type.isPrimitive() && type != int.class)
continue; //FIXME
testUnreflectSetter(lookup, f, type, value);
}
}
public void testUnreflectSetter(MethodHandles.Lookup lookup,
Field f, Class<?> type, Object value) throws Throwable {
countTest(true);
boolean isStatic = Modifier.isStatic(f.getModifiers());
MethodType expType = MethodType.methodType(void.class, HasFields.class, type);
if (isStatic) expType = expType.dropParameterTypes(0, 1);
MethodHandle mh = lookup.unreflectSetter(f);
assertSame(mh.type(), expType);
assertEquals(mh.toString(), f.getName());
HasFields fields = new HasFields();
Object sawValue;
Class<?> vtype = type;
if (type != int.class) vtype = Object.class;
int last = mh.type().parameterCount() - 1;
mh = MethodHandles.convertArguments(mh, mh.type().generic().changeReturnType(void.class).changeParameterType(last, vtype));
assertEquals(f.get(fields), value); // clean to start with
for (int i = 0; i <= 1; i++) {
Object putValue = randomArg(type);
if (isStatic) {
if (type == int.class)
mh.<void>invoke((int)(Integer)putValue); // do these exactly
else
mh.<void>invoke(putValue);
} else {
if (type == int.class)
mh.<void>invoke((Object) fields, (int)(Integer)putValue);
else
mh.<void>invoke((Object) fields, putValue);
}
assertEquals(f.get(fields), putValue);
}
f.set(fields, value); // put it back
}
@Test @Ignore("unimplemented")
@Test
public void testArrayElementGetter() throws Throwable {
startTest("arrayElementGetter");
Class<?> arrayClass = null;
MethodHandle expResult = null;
MethodHandle result = MethodHandles.arrayElementGetter(arrayClass);
assertEquals(expResult, result);
fail("The test case is a prototype.");
testArrayElementGetterSetter(new Object[10], false);
testArrayElementGetterSetter(new String[10], false);
testArrayElementGetterSetter(new int[10], false);
// FIXME: Do the other primitive types.
//testArrayElementGetterSetter(new float[10], false);
}
@Test @Ignore("unimplemented")
@Test
public void testArrayElementSetter() throws Throwable {
startTest("arrayElementSetter");
Class<?> arrayClass = null;
MethodHandle expResult = null;
MethodHandle result = MethodHandles.arrayElementSetter(arrayClass);
assertEquals(expResult, result);
fail("The test case is a prototype.");
testArrayElementGetterSetter(new Object[10], true);
testArrayElementGetterSetter(new String[10], true);
testArrayElementGetterSetter(new int[10], true);
// FIXME: Do the other primitive types.
//testArrayElementGetterSetter(new float[10], true);
}
public void testArrayElementGetterSetter(Object array, boolean testSetter) throws Throwable {
countTest(true);
Class<?> arrayType = array.getClass();
Class<?> elemType = arrayType.getComponentType();
MethodType expType = !testSetter
? MethodType.methodType(elemType, arrayType, int.class)
: MethodType.methodType(void.class, arrayType, int.class, elemType);
MethodHandle mh = !testSetter
? MethodHandles.arrayElementGetter(arrayType)
: MethodHandles.arrayElementSetter(arrayType);
assertSame(mh.type(), expType);
//assertEquals(mh.toString(), f.getName());
Object sawValue, expValue;
List<Object> model = array2list(array);
int length = Array.getLength(array);
for (int i = 0; i < length; i++) {
// update array element
Object random = randomArg(elemType);
model.set(i, random);
if (testSetter) {
if (elemType == int.class)
mh.<void>invoke((int[]) array, i, (int)(Integer)random);
else
mh.invokeGeneric(array, i, random);
assertEquals(model, array2list(array));
} else {
Array.set(array, i, random);
}
// observe array element
sawValue = Array.get(array, i);
if (!testSetter) {
expValue = sawValue;
if (elemType == int.class)
sawValue = mh.<int>invoke((int[]) array, i);
else
sawValue = mh.invokeGeneric(array, i);
assertEquals(sawValue, expValue);
assertEquals(model, array2list(array));
}
}
}
List<Object> array2list(Object array) {
int length = Array.getLength(array);
ArrayList<Object> model = new ArrayList<Object>(length);
for (int i = 0; i < length; i++)
model.add(Array.get(array, i));
return model;
}
static class Callee {
......@@ -663,11 +882,11 @@ public class MethodHandlesTest {
}
static MethodHandle ofType(Class<?> rtype, int n) {
if (n == -1)
return ofType(MethodType.make(rtype, Object[].class));
return ofType(MethodType.makeGeneric(n).changeReturnType(rtype));
return ofType(MethodType.methodType(rtype, Object[].class));
return ofType(MethodType.genericMethodType(n).changeReturnType(rtype));
}
static MethodHandle ofType(Class<?> rtype, Class<?>... ptypes) {
return ofType(MethodType.make(rtype, ptypes));
return ofType(MethodType.methodType(rtype, ptypes));
}
static MethodHandle ofType(MethodType type) {
Class<?> rtype = type.returnType();
......@@ -701,7 +920,7 @@ public class MethodHandlesTest {
if (params[i] == null) params[i] = idType.parameterType(i);
}
// simulate the pairwise conversion
MethodType newType = MethodType.make(rtype, params);
MethodType newType = MethodType.methodType(rtype, params);
Object[] args = randomArgs(newType.parameterArray());
Object[] convArgs = args.clone();
for (int i = 0; i < args.length; i++) {
......@@ -710,7 +929,7 @@ public class MethodHandlesTest {
if (src != dst)
convArgs[i] = castToWrapper(convArgs[i], dst);
}
Object convResult = MethodHandles.invoke(id, convArgs);
Object convResult = id.invokeVarargs(convArgs);
{
Class<?> dst = newType.returnType();
Class<?> src = idType.returnType();
......@@ -732,12 +951,232 @@ public class MethodHandlesTest {
if (!positive) return; // negative test failed as expected
assertEquals(newType, target.type());
printCalled(target, id.toString(), args);
Object result = MethodHandles.invoke(target, args);
Object result = target.invokeVarargs(args);
assertCalled(name, convArgs);
assertEquals(convResult, result);
System.out.print(':');
}
@Test
public void testPermuteArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("permuteArguments");
testPermuteArguments(4, Integer.class, 2, String.class, 0);
//testPermuteArguments(6, Integer.class, 0, null, 30);
//testPermuteArguments(4, Integer.class, 1, int.class, 6);
}
public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
if (verbosity >= 1)
System.out.println("permuteArguments "+max+"*"+type1.getName()
+(t2c==0?"":"/"+t2c+"*"+type2.getName())
+(dilution > 0 ? " with dilution "+dilution : ""));
int t2pos = t2c == 0 ? 0 : 1;
for (int inargs = t2pos+1; inargs <= max; inargs++) {
Class<?>[] types = new Class<?>[inargs];
Arrays.fill(types, type1);
if (t2c != 0) {
// Fill in a middle range with type2:
Arrays.fill(types, t2pos, Math.min(t2pos+t2c, inargs), type2);
}
Object[] args = randomArgs(types);
int numcases = 1;
for (int outargs = 0; outargs <= max; outargs++) {
if (outargs - inargs >= MAX_ARG_INCREASE) continue;
int[] reorder = new int[outargs];
int casStep = dilution + 1;
// Avoid some common factors:
while ((casStep > 2 && casStep % 2 == 0 && inargs % 2 == 0) ||
(casStep > 3 && casStep % 3 == 0 && inargs % 3 == 0))
casStep++;
for (int cas = 0; cas < numcases; cas += casStep) {
for (int i = 0, c = cas; i < outargs; i++) {
reorder[i] = c % inargs;
c /= inargs;
}
testPermuteArguments(args, types, reorder);
}
numcases *= inargs;
if (dilution > 10 && outargs >= 4) {
// Do some special patterns, which we probably missed.
// Replication of a single argument or argument pair.
for (int i = 0; i < inargs; i++) {
Arrays.fill(reorder, i);
testPermuteArguments(args, types, reorder);
for (int d = 1; d <= 2; d++) {
if (i + d >= inargs) continue;
for (int j = 1; j < outargs; j += 2)
reorder[j] += 1;
testPermuteArguments(args, types, reorder);
testPermuteArguments(args, types, reverse(reorder));
}
}
// Repetition of a sequence of 3 or more arguments.
for (int i = 1; i < inargs; i++) {
for (int len = 3; len <= inargs; len++) {
for (int j = 0; j < outargs; j++)
reorder[j] = (i + (j % len)) % inargs;
testPermuteArguments(args, types, reorder);
testPermuteArguments(args, types, reverse(reorder));
}
}
}
}
}
}
static int[] reverse(int[] reorder) {
reorder = reorder.clone();
for (int i = 0, imax = reorder.length / 2; i < imax; i++) {
int j = reorder.length - 1 - i;
int tem = reorder[i];
reorder[i] = reorder[j];
reorder[j] = tem;
}
return reorder;
}
void testPermuteArguments(Object[] args, Class<?>[] types, int[] reorder) throws Throwable {
countTest();
if (args == null && types == null) {
int max = 0;
for (int j : reorder) {
if (max < j) max = j;
}
args = randomArgs(max+1, Integer.class);
}
if (args == null) {
args = randomArgs(types);
}
if (types == null) {
types = new Class<?>[args.length];
for (int i = 0; i < args.length; i++)
types[i] = args[i].getClass();
}
int inargs = args.length, outargs = reorder.length;
assert(inargs == types.length);
if (verbosity >= 2)
System.out.println("permuteArguments "+Arrays.toString(reorder));
Object[] permArgs = new Object[outargs];
Class<?>[] permTypes = new Class<?>[outargs];
for (int i = 0; i < outargs; i++) {
permArgs[i] = args[reorder[i]];
permTypes[i] = types[reorder[i]];
}
if (verbosity >= 3) {
System.out.println("in args: "+Arrays.asList(args));
System.out.println("out args: "+Arrays.asList(permArgs));
System.out.println("in types: "+Arrays.asList(types));
System.out.println("out types: "+Arrays.asList(permTypes));
}
MethodType inType = MethodType.methodType(Object.class, types);
MethodType outType = MethodType.methodType(Object.class, permTypes);
MethodHandle target = MethodHandles.convertArguments(ValueConversions.varargsList(outargs), outType);
MethodHandle newTarget = MethodHandles.permuteArguments(target, inType, reorder);
Object result = newTarget.invokeVarargs(args);
Object expected = Arrays.asList(permArgs);
assertEquals(expected, result);
}
@Test
public void testSpreadArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("spreadArguments");
for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
if (verbosity >= 2)
System.out.println("spreadArguments "+argType);
for (int nargs = 0; nargs < 10; nargs++) {
if (argType == int.class && nargs >= 6) continue; // FIXME Fail_1
for (int pos = 0; pos < nargs; pos++) {
if (argType == int.class && pos > 0) continue; // FIXME Fail_3
testSpreadArguments(argType, pos, nargs);
}
}
}
}
public void testSpreadArguments(Class<?> argType, int pos, int nargs) throws Throwable {
countTest();
MethodHandle target = ValueConversions.varargsArray(nargs);
MethodHandle target2 = changeArgTypes(target, argType);
if (verbosity >= 2)
System.out.println("spread into "+target2+" ["+pos+".."+nargs+"]");
Object[] args = randomArgs(target2.type().parameterArray());
// make sure the target does what we think it does:
if (pos == 0 && nargs < 5) {
Object[] check = (Object[]) target.invokeVarargs(args);
assertArrayEquals(args, check);
switch (nargs) {
case 0:
check = target.<Object[]>invoke();
assertArrayEquals(args, check);
break;
case 1:
check = target.<Object[]>invoke(args[0]);
assertArrayEquals(args, check);
break;
case 2:
check = target.<Object[]>invoke(args[0], args[1]);
assertArrayEquals(args, check);
break;
}
}
List<Class<?>> newParams = new ArrayList<Class<?>>(target2.type().parameterList());
{ // modify newParams in place
List<Class<?>> spreadParams = newParams.subList(pos, nargs);
spreadParams.clear(); spreadParams.add(Object[].class);
}
MethodType newType = MethodType.methodType(Object.class, newParams);
MethodHandle result = MethodHandles.spreadArguments(target2, newType);
Object[] returnValue;
if (pos == 0) {
returnValue = (Object[]) result.invoke(args);
} else {
Object[] args1 = Arrays.copyOfRange(args, 0, pos+1);
args1[pos] = Arrays.copyOfRange(args, pos, args.length);
returnValue = (Object[]) result.invokeVarargs(args1);
}
assertArrayEquals(args, returnValue);
}
@Test
public void testCollectArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("collectArguments");
for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
if (verbosity >= 2)
System.out.println("collectArguments "+argType);
for (int nargs = 0; nargs < 10; nargs++) {
for (int pos = 0; pos < nargs; pos++) {
if (argType == int.class) continue; // FIXME Fail_4
testCollectArguments(argType, pos, nargs);
}
}
}
}
public void testCollectArguments(Class<?> argType, int pos, int nargs) throws Throwable {
countTest();
// fake up a MH with the same type as the desired adapter:
MethodHandle fake = ValueConversions.varargsArray(nargs);
fake = changeArgTypes(fake, argType);
MethodType newType = fake.type();
Object[] args = randomArgs(newType.parameterArray());
// here is what should happen:
Object[] collectedArgs = Arrays.copyOfRange(args, 0, pos+1);
collectedArgs[pos] = Arrays.copyOfRange(args, pos, args.length);
// here is the MH which will witness the collected argument tail:
MethodHandle target = ValueConversions.varargsArray(pos+1);
target = changeArgTypes(target, 0, pos, argType);
target = changeArgTypes(target, pos, pos+1, Object[].class);
if (verbosity >= 2)
System.out.println("collect from "+Arrays.asList(args)+" ["+pos+".."+nargs+"]");
MethodHandle result = MethodHandles.collectArguments(target, newType);
Object[] returnValue = (Object[]) result.invokeVarargs(args);
// assertTrue(returnValue.length == pos+1 && returnValue[pos] instanceof Object[]);
// returnValue[pos] = Arrays.asList((Object[]) returnValue[pos]);
// collectedArgs[pos] = Arrays.asList((Object[]) collectedArgs[pos]);
assertArrayEquals(collectedArgs, returnValue);
}
@Test
public void testInsertArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
......@@ -753,7 +1192,6 @@ public class MethodHandlesTest {
}
void testInsertArguments(int nargs, int pos, int ins) throws Throwable {
if (pos != 0 || ins != 1) return; // temp. restriction until MHs.insertArguments
countTest();
MethodHandle target = ValueConversions.varargsArray(nargs + ins);
Object[] args = randomArgs(target.type().parameterArray());
......@@ -762,10 +1200,10 @@ public class MethodHandlesTest {
List<Object> argsToInsert = argsToPass.subList(pos, pos + ins);
if (verbosity >= 2)
System.out.println("insert: "+argsToInsert+" into "+target);
MethodHandle target2 = MethodHandles.insertArgument(target, pos,
argsToInsert.get(0));
MethodHandle target2 = MethodHandles.insertArguments(target, pos,
(Object[]) argsToInsert.toArray());
argsToInsert.clear(); // remove from argsToInsert
Object res2 = MethodHandles.invoke(target2, argsToPass.toArray());
Object res2 = target2.invokeVarargs(argsToPass);
Object res2List = Arrays.asList((Object[])res2);
if (verbosity >= 2)
System.out.println("result: "+res2List);
......@@ -774,6 +1212,244 @@ public class MethodHandlesTest {
assertEquals(resList, res2List);
}
@Test
public void testFilterArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("filterArguments");
for (int nargs = 1; nargs <= 6; nargs++) {
for (int pos = 0; pos < nargs; pos++) {
testFilterArguments(nargs, pos);
}
}
}
void testFilterArguments(int nargs, int pos) throws Throwable {
countTest();
MethodHandle target = ValueConversions.varargsList(nargs);
MethodHandle filter = ValueConversions.varargsList(1);
filter = MethodHandles.convertArguments(filter, filter.type().generic());
Object[] argsToPass = randomArgs(nargs, Object.class);
if (verbosity >= 2)
System.out.println("filter "+target+" at "+pos+" with "+filter);
MethodHandle[] filters = new MethodHandle[pos*2+1];
filters[pos] = filter;
MethodHandle target2 = MethodHandles.filterArguments(target, filters);
// Simulate expected effect of filter on arglist:
Object[] filteredArgs = argsToPass.clone();
filteredArgs[pos] = filter.invoke(filteredArgs[pos]);
List<Object> expected = Arrays.asList(filteredArgs);
Object result = target2.invokeVarargs(argsToPass);
if (verbosity >= 2)
System.out.println("result: "+result);
if (!expected.equals(result))
System.out.println("*** fail at n/p = "+nargs+"/"+pos+": "+argsToPass+" => "+result);
assertEquals(expected, result);
}
@Test
public void testFoldArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("foldArguments");
for (int nargs = 0; nargs <= 4; nargs++) {
for (int fold = 0; fold <= nargs; fold++) {
for (int pos = 0; pos <= nargs; pos++) {
testFoldArguments(nargs, pos, fold);
}
}
}
}
void testFoldArguments(int nargs, int pos, int fold) throws Throwable {
if (pos != 0) return; // can fold only at pos=0 for now
countTest();
MethodHandle target = ValueConversions.varargsList(1 + nargs);
MethodHandle combine = ValueConversions.varargsList(fold);
List<Object> argsToPass = Arrays.asList(randomArgs(nargs, Object.class));
if (verbosity >= 2)
System.out.println("fold "+target+" with "+combine);
MethodHandle target2 = MethodHandles.foldArguments(target, combine);
// Simulate expected effect of combiner on arglist:
List<Object> expected = new ArrayList<Object>(argsToPass);
List<Object> argsToFold = expected.subList(pos, pos + fold);
if (verbosity >= 2)
System.out.println("fold: "+argsToFold+" into "+target2);
Object foldedArgs = combine.invokeVarargs(argsToFold);
argsToFold.add(0, foldedArgs);
Object result = target2.invokeVarargs(argsToPass);
if (verbosity >= 2)
System.out.println("result: "+result);
if (!expected.equals(result))
System.out.println("*** fail at n/p/f = "+nargs+"/"+pos+"/"+fold+": "+argsToPass+" => "+result);
assertEquals(expected, result);
}
@Test
public void testDropArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("dropArguments");
for (int nargs = 0; nargs <= 4; nargs++) {
for (int drop = 1; drop <= 4; drop++) {
for (int pos = 0; pos <= nargs; pos++) {
testDropArguments(nargs, pos, drop);
}
}
}
}
void testDropArguments(int nargs, int pos, int drop) throws Throwable {
countTest();
MethodHandle target = ValueConversions.varargsArray(nargs);
Object[] args = randomArgs(target.type().parameterArray());
MethodHandle target2 = MethodHandles.dropArguments(target, pos,
Collections.nCopies(drop, Object.class).toArray(new Class[0]));
List<Object> resList = Arrays.asList(args);
List<Object> argsToDrop = new ArrayList<Object>(resList);
for (int i = drop; i > 0; i--) {
argsToDrop.add(pos, "blort#"+i);
}
Object res2 = target2.invokeVarargs(argsToDrop);
Object res2List = Arrays.asList((Object[])res2);
//if (!resList.equals(res2List))
// System.out.println("*** fail at n/p/d = "+nargs+"/"+pos+"/"+drop+": "+argsToDrop+" => "+res2List);
assertEquals(resList, res2List);
}
@Test
public void testInvokers() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("exactInvoker, genericInvoker, varargsInvoker, dynamicInvoker");
// exactInvoker, genericInvoker, varargsInvoker[0..N], dynamicInvoker
Set<MethodType> done = new HashSet<MethodType>();
for (int i = 0; i <= 6; i++) {
MethodType gtype = MethodType.genericMethodType(i);
for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
for (int j = -1; j < i; j++) {
MethodType type = gtype;
if (j < 0)
type = type.changeReturnType(argType);
else if (argType == void.class)
continue;
else
type = type.changeParameterType(j, argType);
if (argType.isPrimitive() && j != i-1) continue; // FIXME Fail_5
if (done.add(type))
testInvokers(type);
MethodType vtype = type.changeReturnType(void.class);
if (done.add(vtype))
testInvokers(vtype);
}
}
}
}
public void testInvokers(MethodType type) throws Throwable {
if (verbosity >= 2)
System.out.println("test invokers for "+type);
int nargs = type.parameterCount();
boolean testRetCode = type.returnType() != void.class;
MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "invokee",
MethodType.genericMethodType(0, true));
target = MethodHandles.collectArguments(target, type);
Object[] args = randomArgs(type.parameterArray());
List<Object> targetPlusArgs = new ArrayList<Object>(Arrays.asList(args));
targetPlusArgs.add(0, target);
int code = (Integer) invokee(args);
Object log = logEntry("invokee", args);
assertEquals(log.hashCode(), code);
assertCalled("invokee", args);
MethodHandle inv;
Object result;
// exact invoker
countTest();
calledLog.clear();
inv = MethodHandles.exactInvoker(type);
result = inv.invokeVarargs(targetPlusArgs);
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
// generic invoker
countTest();
inv = MethodHandles.genericInvoker(type);
if (nargs <= 3) {
calledLog.clear();
switch (nargs) {
case 0:
result = inv.invoke(target);
break;
case 1:
result = inv.invoke(target, args[0]);
break;
case 2:
result = inv.invoke(target, args[0], args[1]);
break;
case 3:
result = inv.invoke(target, args[0], args[1], args[2]);
break;
}
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
}
calledLog.clear();
result = inv.invokeVarargs(targetPlusArgs);
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
// varargs invoker #0
calledLog.clear();
inv = MethodHandles.varargsInvoker(type, 0);
result = inv.invoke(target, args);
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
if (nargs >= 1) {
// varargs invoker #1
calledLog.clear();
inv = MethodHandles.varargsInvoker(type, 1);
result = inv.invoke(target, args[0], Arrays.copyOfRange(args, 1, nargs));
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
}
if (nargs >= 2) {
// varargs invoker #2
calledLog.clear();
inv = MethodHandles.varargsInvoker(type, 2);
result = inv.invoke(target, args[0], args[1], Arrays.copyOfRange(args, 2, nargs));
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
}
if (nargs >= 3) {
// varargs invoker #3
calledLog.clear();
inv = MethodHandles.varargsInvoker(type, 3);
result = inv.invoke(target, args[0], args[1], args[2], Arrays.copyOfRange(args, 3, nargs));
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
}
for (int k = 0; k <= nargs; k++) {
// varargs invoker #0..N
countTest();
calledLog.clear();
inv = MethodHandles.varargsInvoker(type, k);
List<Object> targetPlusVarArgs = new ArrayList<Object>(targetPlusArgs);
List<Object> tailList = targetPlusVarArgs.subList(1+k, 1+nargs);
Object[] tail = tailList.toArray();
tailList.clear(); tailList.add(tail);
result = inv.invokeVarargs(targetPlusVarArgs);
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
}
// dynamic invoker
countTest();
CallSite site = new CallSite(MethodHandlesTest.class, "foo", type);
inv = MethodHandles.dynamicInvoker(site);
site.setTarget(target);
calledLog.clear();
result = inv.invokeVarargs(args);
if (testRetCode) assertEquals(code, result);
assertCalled("invokee", args);
}
static Object invokee(Object... args) {
return called("invokee", args).hashCode();
}
private static final String MISSING_ARG = "missingArg";
static Object targetIfEquals() {
return called("targetIfEquals");
......@@ -806,6 +1482,228 @@ public class MethodHandlesTest {
return called("fallbackIfNotEquals", x, y, z);
}
@Test
public void testGuardWithTest() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("guardWithTest");
for (int nargs = 0; nargs <= 3; nargs++) {
if (nargs != 2) continue; // FIXME: test more later
testGuardWithTest(nargs, Object.class);
testGuardWithTest(nargs, String.class);
}
}
void testGuardWithTest(int nargs, Class<?> argClass) throws Throwable {
countTest();
MethodHandle test = PRIVATE.findVirtual(Object.class, "equals", MethodType.methodType(boolean.class, Object.class));
MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "targetIfEquals", MethodType.genericMethodType(nargs));
MethodHandle fallback = PRIVATE.findStatic(MethodHandlesTest.class, "fallbackIfNotEquals", MethodType.genericMethodType(nargs));
while (test.type().parameterCount() < nargs)
test = MethodHandles.dropArguments(test, test.type().parameterCount()-1, Object.class);
while (test.type().parameterCount() > nargs)
test = MethodHandles.insertArguments(test, 0, MISSING_ARG);
if (argClass != Object.class) {
test = changeArgTypes(test, argClass);
target = changeArgTypes(target, argClass);
fallback = changeArgTypes(fallback, argClass);
}
MethodHandle mh = MethodHandles.guardWithTest(test, target, fallback);
assertEquals(target.type(), mh.type());
Object[][] argLists = {
{ },
{ "foo" }, { MISSING_ARG },
{ "foo", "foo" }, { "foo", "bar" },
{ "foo", "foo", "baz" }, { "foo", "bar", "baz" }
};
for (Object[] argList : argLists) {
if (argList.length != nargs) continue;
boolean equals;
switch (nargs) {
case 0: equals = true; break;
case 1: equals = MISSING_ARG.equals(argList[0]); break;
default: equals = argList[0].equals(argList[1]); break;
}
String willCall = (equals ? "targetIfEquals" : "fallbackIfNotEquals");
if (verbosity >= 2)
System.out.println(logEntry(willCall, argList));
Object result = mh.invokeVarargs(argList);
assertCalled(willCall, argList);
}
}
@Test
public void testCatchException() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("catchException");
for (int nargs = 2; nargs <= 6; nargs++) {
for (int ti = 0; ti <= 1; ti++) {
boolean throwIt = (ti != 0);
testCatchException(int.class, new ClassCastException("testing"), throwIt, nargs);
testCatchException(void.class, new java.io.IOException("testing"), throwIt, nargs);
testCatchException(String.class, new LinkageError("testing"), throwIt, nargs);
}
}
}
private static <T extends Throwable>
Object throwOrReturn(Object normal, T exception) throws T {
if (exception != null) throw exception;
return normal;
}
void testCatchException(Class<?> returnType, Throwable thrown, boolean throwIt, int nargs) throws Throwable {
countTest();
if (verbosity >= 2)
System.out.println("catchException rt="+returnType+" throw="+throwIt+" nargs="+nargs);
Class<? extends Throwable> exType = thrown.getClass();
MethodHandle throwOrReturn
= PRIVATE.findStatic(MethodHandlesTest.class, "throwOrReturn",
MethodType.methodType(Object.class, Object.class, Throwable.class));
MethodHandle thrower = throwOrReturn;
while (thrower.type().parameterCount() < nargs)
thrower = MethodHandles.dropArguments(thrower, thrower.type().parameterCount(), Object.class);
MethodHandle target = MethodHandles.catchException(thrower,
thrown.getClass(), ValueConversions.varargsList(1+nargs));
assertEquals(thrower.type(), target.type());
//System.out.println("catching with "+target+" : "+throwOrReturn);
Object[] args = randomArgs(nargs, Object.class);
args[1] = (throwIt ? thrown : null);
Object returned = target.invokeVarargs(args);
//System.out.println("return from "+target+" : "+returned);
if (!throwIt) {
assertSame(args[0], returned);
} else {
List<Object> catchArgs = new ArrayList<Object>(Arrays.asList(args));
catchArgs.add(0, thrown);
assertEquals(catchArgs, returned);
}
}
@Test
public void testThrowException() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("throwException");
testThrowException(int.class, new ClassCastException("testing"));
testThrowException(void.class, new java.io.IOException("testing"));
testThrowException(String.class, new LinkageError("testing"));
}
void testThrowException(Class<?> returnType, Throwable thrown) throws Throwable {
countTest();
Class<? extends Throwable> exType = thrown.getClass();
MethodHandle target = MethodHandles.throwException(returnType, exType);
//System.out.println("throwing with "+target+" : "+thrown);
MethodType expectedType = MethodType.methodType(returnType, exType);
assertEquals(expectedType, target.type());
Throwable caught = null;
try {
Object res = target.invokeGeneric(thrown);
fail("got "+res+" instead of throwing "+thrown);
} catch (Throwable ex) {
if (ex != thrown) {
if (ex instanceof Error) throw (Error)ex;
if (ex instanceof RuntimeException) throw (RuntimeException)ex;
}
caught = ex;
}
assertSame(thrown, caught);
}
@Test
public void testCastFailure() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("testCastFailure");
testCastFailure("cast/argument", 11000);
testCastFailure("unbox/argument", 11000);
testCastFailure("cast/return", 11000);
testCastFailure("unbox/return", 11000);
}
static class Surprise extends JavaMethodHandle {
Surprise() { super("value"); }
Object value(Object x) {
trace("value", x);
if (boo != null) return boo;
return x;
}
Object boo;
void boo(Object x) { boo = x; }
static void trace(String x, Object y) {
if (verbosity > 8) System.out.println(x+"="+y);
}
static Object refIdentity(Object x) { trace("ref.x", x); return x; }
static Integer boxIdentity(Integer x) { trace("box.x", x); return x; }
static int intIdentity(int x) { trace("int.x", x); return x; }
static MethodHandle REF_IDENTITY = PRIVATE.findStatic(
Surprise.class, "refIdentity",
MethodType.methodType(Object.class, Object.class));
static MethodHandle BOX_IDENTITY = PRIVATE.findStatic(
Surprise.class, "boxIdentity",
MethodType.methodType(Integer.class, Integer.class));
static MethodHandle INT_IDENTITY = PRIVATE.findStatic(
Surprise.class, "intIdentity",
MethodType.methodType(int.class, int.class));
}
void testCastFailure(String mode, int okCount) throws Throwable {
countTest(false);
if (verbosity > 1) System.out.println("mode="+mode);
Surprise boo = new Surprise();
MethodHandle identity = Surprise.REF_IDENTITY, surprise = boo;
if (mode.endsWith("/return")) {
if (mode.equals("unbox/return")) {
// fail on return to ((Integer)surprise).intValue
surprise = MethodHandles.convertArguments(surprise, MethodType.methodType(int.class, Object.class));
identity = MethodHandles.convertArguments(identity, MethodType.methodType(int.class, Object.class));
} else if (mode.equals("cast/return")) {
// fail on return to (Integer)surprise
surprise = MethodHandles.convertArguments(surprise, MethodType.methodType(Integer.class, Object.class));
identity = MethodHandles.convertArguments(identity, MethodType.methodType(Integer.class, Object.class));
}
} else if (mode.endsWith("/argument")) {
MethodHandle callee = null;
if (mode.equals("unbox/argument")) {
// fail on handing surprise to int argument
callee = Surprise.INT_IDENTITY;
} else if (mode.equals("cast/argument")) {
// fail on handing surprise to Integer argument
callee = Surprise.BOX_IDENTITY;
}
if (callee != null) {
callee = MethodHandles.convertArguments(callee, MethodType.genericMethodType(1));
surprise = MethodHandles.filterArguments(callee, surprise);
identity = MethodHandles.filterArguments(callee, identity);
}
}
assertNotSame(mode, surprise, boo);
identity = MethodHandles.convertArguments(identity, MethodType.genericMethodType(1));
surprise = MethodHandles.convertArguments(surprise, MethodType.genericMethodType(1));
Object x = 42;
for (int i = 0; i < okCount; i++) {
Object y = identity.invoke(x);
assertEquals(x, y);
Object z = surprise.invoke(x);
assertEquals(x, z);
}
boo.boo("Boo!");
Object y = identity.invoke(x);
assertEquals(x, y);
try {
Object z = surprise.invoke(x);
System.out.println("Failed to throw; got z="+z);
assertTrue(false);
} catch (Exception ex) {
if (verbosity > 1)
System.out.println("caught "+ex);
if (verbosity > 2)
ex.printStackTrace();
assertTrue(ex instanceof ClassCastException
// FIXME: accept only one of the two for any given unit test
|| ex instanceof WrongMethodTypeException
);
}
}
}
// Local abbreviated copy of sun.dyn.util.ValueConversions
class ValueConversions {
......@@ -846,7 +1744,7 @@ class ValueConversions {
MethodHandles.Lookup lookup = IMPL_LOOKUP;
for (;;) {
int nargs = arrays.size();
MethodType type = MethodType.makeGeneric(nargs).changeReturnType(Object[].class);
MethodType type = MethodType.genericMethodType(nargs).changeReturnType(Object[].class);
String name = "array";
MethodHandle array = null;
try {
......@@ -870,6 +1768,67 @@ class ValueConversions {
// else need to spin bytecode or do something else fancy
throw new UnsupportedOperationException("NYI");
}
private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
private static List<Object> list() { return NO_ARGS_LIST; }
private static List<Object> list(Object a0)
{ return makeList(a0); }
private static List<Object> list(Object a0, Object a1)
{ return makeList(a0, a1); }
private static List<Object> list(Object a0, Object a1, Object a2)
{ return makeList(a0, a1, a2); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
{ return makeList(a0, a1, a2, a3); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4)
{ return makeList(a0, a1, a2, a3, a4); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5)
{ return makeList(a0, a1, a2, a3, a4, a5); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6)
{ return makeList(a0, a1, a2, a3, a4, a5, a6); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7)
{ return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8)
{ return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8, Object a9)
{ return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
static MethodHandle[] makeLists() {
ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
MethodHandles.Lookup lookup = IMPL_LOOKUP;
for (;;) {
int nargs = arrays.size();
MethodType type = MethodType.genericMethodType(nargs).changeReturnType(List.class);
String name = "list";
MethodHandle array = null;
try {
array = lookup.findStatic(ValueConversions.class, name, type);
} catch (NoAccessException ex) {
}
if (array == null) break;
arrays.add(array);
}
assert(arrays.size() == 11); // current number of methods
return arrays.toArray(new MethodHandle[0]);
}
static final MethodHandle[] LISTS = makeLists();
/** Return a method handle that takes the indicated number of Object
* arguments and returns List.
*/
public static MethodHandle varargsList(int nargs) {
if (nargs < LISTS.length)
return LISTS[nargs];
// else need to spin bytecode or do something else fancy
throw new UnsupportedOperationException("NYI");
}
}
// This guy tests access from outside the same package member, but inside
// the package itself.
......@@ -878,4 +1837,3 @@ class PackageSibling {
return MethodHandles.lookup();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册