OpenJDK / amber / amber
changeset 9645:dabb5e4edc4c
7034977: JSR 292 MethodHandle.invokeGeneric should be renamed MethodHandle.invoke
Summary: rename invokeGeneric to invoke
Reviewed-by: never, twisti
line wrap: on
line diff
--- a/jdk/src/share/classes/java/lang/invoke/CallSite.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java Thu May 12 19:27:33 2011 -0700 @@ -273,9 +273,9 @@ Object binding; info = maybeReBox(info); if (info == null) { - binding = bootstrapMethod.invokeGeneric(caller, name, type); + binding = bootstrapMethod.invoke(caller, name, type); } else if (!info.getClass().isArray()) { - binding = bootstrapMethod.invokeGeneric(caller, name, type, info); + binding = bootstrapMethod.invoke(caller, name, type, info); } else { Object[] argv = (Object[]) info; maybeReBoxElements(argv); @@ -283,10 +283,10 @@ throw new BootstrapMethodError("too many bootstrap method arguments"); MethodType bsmType = bootstrapMethod.type(); if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class) - binding = bootstrapMethod.invokeGeneric(caller, name, type, argv); + binding = bootstrapMethod.invoke(caller, name, type, argv); else binding = MethodHandles.spreadInvoker(bsmType, 3) - .invokeGeneric(bootstrapMethod, caller, name, type, argv); + .invoke(bootstrapMethod, caller, name, type, argv); } //System.out.println("BSM for "+name+type+" => "+binding); if (binding instanceof CallSite) {
--- a/jdk/src/share/classes/java/lang/invoke/FromGeneric.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/FromGeneric.java Thu May 12 19:27:33 2011 -0700 @@ -160,7 +160,6 @@ /** 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 */
--- a/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java Thu May 12 19:27:33 2011 -0700 @@ -29,12 +29,12 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; /** - * Adapters which manage MethodHandle.invokeGeneric calls. + * Adapters which manage inexact MethodHandle.invoke calls. * The JVM calls one of these when the exact type match fails. * @author jrose */ class InvokeGeneric { - // erased type for the call, which originates from an invokeGeneric site + // erased type for the call, which originates from an inexact invoke site private final MethodType erasedCallerType; // an invoker of type (MT, MH; A...) -> R private final MethodHandle initialInvoker; @@ -56,7 +56,7 @@ } /** Return the adapter information for this type's erasure. */ - /*non-public*/ static MethodHandle genericInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException { + /*non-public*/ static MethodHandle generalInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException { InvokeGeneric gen = new InvokeGeneric(erasedCallerType); return gen.initialInvoker; }
--- a/jdk/src/share/classes/java/lang/invoke/Invokers.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java Thu May 12 19:27:33 2011 -0700 @@ -43,10 +43,10 @@ private /*lazy*/ MethodHandle erasedInvoker; /*lazy*/ MethodHandle erasedInvokerWithDrops; // for InvokeGeneric - // generic (untyped) invoker for the outgoing call - private /*lazy*/ MethodHandle genericInvoker; + // general invoker for the outgoing call + private /*lazy*/ MethodHandle generalInvoker; - // generic (untyped) invoker for the outgoing call; accepts a single Object[] + // general invoker for the outgoing call; accepts a single Object[] private final /*lazy*/ MethodHandle[] spreadInvokers; // invoker for an unbound callsite @@ -77,13 +77,13 @@ return invoker; } - /*non-public*/ MethodHandle genericInvoker() { + /*non-public*/ MethodHandle generalInvoker() { MethodHandle invoker1 = exactInvoker(); - MethodHandle invoker = genericInvoker; + MethodHandle invoker = generalInvoker; if (invoker != null) return invoker; - MethodType genericType = targetType.generic(); - invoker = MethodHandles.convertArguments(invoker1, invokerType(genericType)); - genericInvoker = invoker; + MethodType generalType = targetType.generic(); + invoker = MethodHandles.convertArguments(invoker1, invokerType(generalType)); + generalInvoker = invoker; return invoker; } @@ -93,7 +93,7 @@ if (invoker != null) return invoker; MethodType erasedType = targetType.erase(); if (erasedType == targetType.generic()) - invoker = genericInvoker(); + invoker = generalInvoker(); else invoker = MethodHandles.convertArguments(invoker1, invokerType(erasedType)); erasedInvoker = invoker; @@ -103,7 +103,7 @@ /*non-public*/ MethodHandle spreadInvoker(int objectArgCount) { MethodHandle vaInvoker = spreadInvokers[objectArgCount]; if (vaInvoker != null) return vaInvoker; - MethodHandle gInvoker = genericInvoker(); + MethodHandle gInvoker = generalInvoker(); vaInvoker = gInvoker.asSpreader(Object[].class, targetType.parameterCount() - objectArgCount); spreadInvokers[objectArgCount] = vaInvoker; return vaInvoker;
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Thu May 12 19:27:33 2011 -0700 @@ -53,12 +53,12 @@ * and the kinds of transformations that apply to it. * <p> * A method handle contains a pair of special invoker methods - * called {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}. + * called {@link #invokeExact invokeExact} and {@link #invoke invoke}. * Both invoker methods provide direct access to the method handle's * underlying method, constructor, field, or other operation, * as modified by transformations of arguments and return values. * Both invokers accept calls which exactly match the method handle's own type. - * The {@code invokeGeneric} invoker also accepts a range of other call types. + * The plain, inexact invoker also accepts a range of other call types. * <p> * Method handles are immutable and have no visible state. * Of course, they can be bound to underlying methods or data which exhibit state. @@ -76,7 +76,7 @@ * may change from time to time or across implementations from different vendors. * * <h3>Method handle compilation</h3> - * A Java method call expression naming {@code invokeExact} or {@code invokeGeneric} + * A Java method call expression naming {@code invokeExact} or {@code invoke} * can invoke a method handle from Java source code. * From the viewpoint of source code, these methods can take any arguments * and their result can be cast to any return type. @@ -86,7 +86,7 @@ * which connects this freedom of invocation directly to the JVM execution stack. * <p> * As is usual with virtual methods, source-level calls to {@code invokeExact} - * and {@code invokeGeneric} compile to an {@code invokevirtual} instruction. + * and {@code invoke} compile to an {@code invokevirtual} instruction. * More unusually, the compiler must record the actual argument types, * and may not perform method invocation conversions on the arguments. * Instead, it must push them on the stack according to their own unconverted types. @@ -109,7 +109,7 @@ * The first time a {@code invokevirtual} instruction is executed * it is linked, by symbolically resolving the names in the instruction * and verifying that the method call is statically legal. - * This is true of calls to {@code invokeExact} and {@code invokeGeneric}. + * This is true of calls to {@code invokeExact} and {@code invoke}. * In this case, the type descriptor emitted by the compiler is checked for * correct syntax and names it contains are resolved. * Thus, an {@code invokevirtual} instruction which invokes @@ -127,18 +127,18 @@ * In the case of {@code invokeExact}, the type descriptor of the invocation * (after resolving symbolic type names) must exactly match the method type * of the receiving method handle. - * In the case of {@code invokeGeneric}, the resolved type descriptor + * In the case of plain, inexact {@code invoke}, the resolved type descriptor * must be a valid argument to the receiver's {@link #asType asType} method. - * Thus, {@code invokeGeneric} is more permissive than {@code invokeExact}. + * Thus, plain {@code invoke} is more permissive than {@code invokeExact}. * <p> * After type matching, a call to {@code invokeExact} directly * and immediately invoke the method handle's underlying method * (or other behavior, as the case may be). * <p> - * A call to {@code invokeGeneric} works the same as a call to + * A call to plain {@code invoke} works the same as a call to * {@code invokeExact}, if the type descriptor specified by the caller * exactly matches the method handle's own type. - * If there is a type mismatch, {@code invokeGeneric} attempts + * If there is a type mismatch, {@code invoke} attempts * to adjust the type of the receiving method handle, * as if by a call to {@link #asType asType}, * to obtain an exactly invokable method handle {@code M2}. @@ -152,7 +152,7 @@ * In typical programs, method handle type matching will usually succeed. * But if a match fails, the JVM will throw a {@link WrongMethodTypeException}, * either directly (in the case of {@code invokeExact}) or indirectly as if - * by a failed call to {@code asType} (in the case of {@code invokeGeneric}). + * by a failed call to {@code asType} (in the case of {@code invoke}). * <p> * Thus, a method type mismatch which might show up as a linkage error * in a statically typed program can show up as @@ -249,8 +249,8 @@ mt = MethodType.methodType(java.util.List.class, Object[].class); mh = lookup.findStatic(java.util.Arrays.class, "asList", mt); assert(mh.isVarargsCollector()); -x = mh.invokeGeneric("one", "two"); -// invokeGeneric(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; +x = mh.invoke("one", "two"); +// invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; assert(x.equals(java.util.Arrays.asList("one","two"))); // mt is (Object,Object,Object)Object mt = MethodType.genericMethodType(3); @@ -269,12 +269,12 @@ mh.invokeExact(System.out, "Hello, world."); // invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V * </pre></blockquote> - * Each of the above calls to {@code invokeExact} or {@code invokeGeneric} + * Each of the above calls to {@code invokeExact} or plain {@code invoke} * generates a single invokevirtual instruction with * the type descriptor indicated in the following comment. * * <h3>Exceptions</h3> - * The methods {@code invokeExact} and {@code invokeGeneric} are declared + * The methods {@code invokeExact} and {@code invoke} are declared * to throw {@link java.lang.Throwable Throwable}, * which is to say that there is no static restriction on what a method handle * can throw. Since the JVM does not distinguish between checked @@ -288,7 +288,7 @@ * * <h3><a name="sigpoly"></a>Signature polymorphism</h3> * The unusual compilation and linkage behavior of - * {@code invokeExact} and {@code invokeGeneric} + * {@code invokeExact} and plain {@code invoke} * is referenced by the term <em>signature polymorphism</em>. * A signature polymorphic method is one which can operate with * any of a wide range of call signatures and return types. @@ -322,7 +322,7 @@ * The following methods (and no others) are signature polymorphic: * <ul> * <li>{@link java.lang.invoke.MethodHandle#invokeExact MethodHandle.invokeExact} - * <li>{@link java.lang.invoke.MethodHandle#invokeGeneric MethodHandle.invokeGeneric} + * <li>{@link java.lang.invoke.MethodHandle#invoke MethodHandle.invoke} * </ul> * <p> * A signature polymorphic method will be declared with the following properties: @@ -374,24 +374,34 @@ * <p> * As a special case, * when the Core Reflection API is used to view the signature polymorphic - * methods {@code invokeExact} or {@code invokeGeneric} in this class, - * they appear as single, non-polymorphic native methods. - * Calls to these native methods do not result in method handle invocations. + * methods {@code invokeExact} or plain {@code invoke} in this class, + * they appear as ordinary non-polymorphic methods. + * Their reflective appearance, as viewed by + * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod}, + * is unaffected by their special status in this API. + * For example, {@link java.lang.reflect.Method#getModifiers Method.getModifiers} + * will report exactly those modifier bits required for any similarly + * declared method, including in this case {@code native} and {@code varargs} bits. + * <p> + * As with any reflected method, these methods (when reflected) may be + * invoked via {@link java.lang.reflect.Method#invoke Method.invoke}. + * However, such reflective calls do not result in method handle invocations. + * Such a call, if passed the required argument + * (a single one, of type {@code Object[]}), will ignore the argument and + * will throw an {@code UnsupportedOperationException}. + * <p> * Since {@code invokevirtual} instructions can natively * invoke method handles under any type descriptor, this reflective view conflicts - * with the normal presentation via bytecodes. - * Thus, these two native methods, as viewed by - * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod}, - * are placeholders only. - * If invoked via {@link java.lang.reflect.Method#invoke Method.invoke}, - * they will throw {@code UnsupportedOperationException}. + * with the normal presentation of these methods via bytecodes. + * Thus, these two native methods, when reflectively viewed by + * {@code Class.getDeclaredMethod}, may be regarded as placeholders only. * <p> * In order to obtain an invoker method for a particular type descriptor, * use {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker}, - * or {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}. + * or {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}. * The {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual} * API is also able to return a method handle - * to call {@code invokeExact} or {@code invokeGeneric}, + * to call {@code invokeExact} or plain {@code invoke}, * for any specified type descriptor . * * <h3>Interoperation between method handles and Java generics</h3> @@ -523,7 +533,7 @@ * adaptations directly on the caller's arguments, * and call the target method handle according to its own exact type. * <p> - * The type descriptor at the call site of {@code invokeGeneric} must + * The type descriptor at the call site of {@code invoke} must * be a valid argument to the receivers {@code asType} method. * In particular, the caller must specify the same argument arity * as the callee's type, @@ -539,11 +549,18 @@ * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call */ + public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable; + + /** + * <em>Temporary alias</em> for {@link #invoke}, for backward compatibility with some versions of JSR 292. + * On some JVMs, support can be excluded by the flags {@code -XX:+UnlockExperimentalVMOptions -XX:-AllowInvokeGeneric}. + * @deprecated Will be removed for JSR 292 Proposed Final Draft. + */ public final native @PolymorphicSignature Object invokeGeneric(Object... args) throws Throwable; /** * Performs a varargs invocation, passing the arguments in the given array - * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site + * to the method handle, as if via an inexact {@link #invoke invoke} from a call site * which mentions only the type {@code Object}, and whose arity is the length * of the argument array. * <p> @@ -553,7 +570,7 @@ * <ul> * <li>Determine the length of the argument array as {@code N}. * For a null reference, {@code N=0}. </li> - * <li>Determine the generic type {@code TN} of {@code N} arguments as + * <li>Determine the general type {@code TN} of {@code N} arguments as * as {@code TN=MethodType.genericMethodType(N)}.</li> * <li>Force the original target method handle {@code MH0} to the * required type, as {@code MH1 = MH0.asType(TN)}. </li> @@ -580,7 +597,7 @@ * Object result = invoker.invokeExact(this, arguments); * </pre></blockquote> * <p> - * Unlike the signature polymorphic methods {@code invokeExact} and {@code invokeGeneric}, + * Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke}, * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI. * It can therefore be used as a bridge between native or reflective code and method handles. * @@ -595,11 +612,11 @@ int argc = arguments == null ? 0 : arguments.length; MethodType type = type(); if (type.parameterCount() != argc) { - // simulate invokeGeneric + // simulate invoke return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments); } if (argc <= 10) { - MethodHandle invoker = type.invokers().genericInvoker(); + MethodHandle invoker = type.invokers().generalInvoker(); switch (argc) { case 0: return invoker.invokeExact(this); case 1: return invoker.invokeExact(this, @@ -644,7 +661,7 @@ /** * Performs a varargs invocation, passing the arguments in the given array - * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site + * to the method handle, as if via an inexact {@link #invoke invoke} from a call site * which mentions only the type {@code Object}, and whose arity is the length * of the argument array. * <p> @@ -672,9 +689,9 @@ * If the original type and new type are equal, returns {@code this}. * <p> * This method provides the crucial behavioral difference between - * {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}. The two methods + * {@link #invokeExact invokeExact} and plain, inexact {@link #invoke invoke}. The two methods * perform the same steps when the caller's type descriptor is identical - * with the callee's, but when the types differ, {@link #invokeGeneric invokeGeneric} + * with the callee's, but when the types differ, plain {@link #invoke invoke} * also calls {@code asType} (or some internal equivalent) in order * to match up the caller's and callee's types. * <p> @@ -798,7 +815,7 @@ * <p> * The type and behavior of the adapter will be the same as * the type and behavior of the target, except that certain - * {@code invokeGeneric} and {@code asType} requests can lead to + * {@code invoke} and {@code asType} requests can lead to * trailing positional arguments being collected into target's * trailing parameter. * Also, the last parameter type of the adapter will be @@ -812,17 +829,17 @@ * since it accepts a whole array of indeterminate length, * rather than a fixed number of arguments.) * <p> - * When called with {@link #invokeGeneric invokeGeneric}, if the caller + * When called with plain, inexact {@link #invoke invoke}, if the caller * type is the same as the adapter, the adapter invokes the target as with * {@code invokeExact}. - * (This is the normal behavior for {@code invokeGeneric} when types match.) + * (This is the normal behavior for {@code invoke} when types match.) * <p> * Otherwise, if the caller and adapter arity are the same, and the * trailing parameter type of the caller is a reference type identical to * or assignable to the trailing parameter type of the adapter, * the arguments and return values are converted pairwise, * as if by {@link MethodHandles#convertArguments convertArguments}. - * (This is also normal behavior for {@code invokeGeneric} in such a case.) + * (This is also normal behavior for {@code invoke} in such a case.) * <p> * Otherwise, the arities differ, or the adapter's trailing parameter * type is not assignable from the corresponding caller type. @@ -838,7 +855,7 @@ * where {@code N} is the arity of the target. * Also, there must exist conversions from the incoming arguments * to the target's arguments. - * As with other uses of {@code invokeGeneric}, if these basic + * As with other uses of plain {@code invoke}, if these basic * requirements are not fulfilled, a {@code WrongMethodTypeException} * may be thrown. * <p> @@ -856,7 +873,7 @@ * <p> * The behavior of {@link #asType asType} is also specialized for * variable arity adapters, to maintain the invariant that - * {@code invokeGeneric} is always equivalent to an {@code asType} + * plain, inexact {@code invoke} is always equivalent to an {@code asType} * call to adjust the target type, followed by {@code invokeExact}. * Therefore, a variable arity adapter responds * to an {@code asType} request by building a fixed arity collector, @@ -893,12 +910,12 @@ MethodHandle asList = publicLookup() .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class)) .asVarargsCollector(Object[].class); -assertEquals("[]", asList.invokeGeneric().toString()); -assertEquals("[1]", asList.invokeGeneric(1).toString()); -assertEquals("[two, too]", asList.invokeGeneric("two", "too").toString()); +assertEquals("[]", asList.invoke().toString()); +assertEquals("[1]", asList.invoke(1).toString()); +assertEquals("[two, too]", asList.invoke("two", "too").toString()); Object[] argv = { "three", "thee", "tee" }; -assertEquals("[three, thee, tee]", asList.invokeGeneric(argv).toString()); -List ls = (List) asList.invokeGeneric((Object)argv); +assertEquals("[three, thee, tee]", asList.invoke(argv).toString()); +List ls = (List) asList.invoke((Object)argv); assertEquals(1, ls.size()); assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0))); * </pre></blockquote> @@ -926,9 +943,9 @@ .asVarargsCollector(Object[].class); MethodHandle mh = MethodHandles.exactInvoker(vamh.type()).bindTo(vamh); assert(vamh.type().equals(mh.type())); -assertEquals("[1, 2, 3]", vamh.invokeGeneric(1,2,3).toString()); +assertEquals("[1, 2, 3]", vamh.invoke(1,2,3).toString()); boolean failed = false; -try { mh.invokeGeneric(1,2,3); } +try { mh.invoke(1,2,3); } catch (WrongMethodTypeException ex) { failed = true; } assert(failed); * </pre></blockquote> @@ -960,7 +977,7 @@ * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle} * which resolves to a variable arity Java method or constructor * </ul> - * @return true if this method handle accepts more than one arity of {@code invokeGeneric} calls + * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls * @see #asVarargsCollector */ public boolean isVarargsCollector() {
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Thu May 12 19:27:33 2011 -0700 @@ -313,7 +313,7 @@ } /** - * The JVM wants to use a MethodType with invokeGeneric. Give the runtime fair warning. + * The JVM wants to use a MethodType with inexact invoke. Give the runtime fair warning. */ static void notifyGenericMethodType(MethodType type) { type.form().notifyGenericMethodType();
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Thu May 12 19:27:33 2011 -0700 @@ -190,7 +190,7 @@ * is not symbolically accessible from the lookup class's loader, * the lookup can still succeed. * For example, lookups for {@code MethodHandle.invokeExact} and - * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type. + * {@code MethodHandle.invoke} will always succeed, regardless of requested type. * <li>If there is a security manager installed, it can forbid the lookup * on various grounds (<a href="#secmgr">see below</a>). * By contrast, the {@code ldc} instruction is not subject to @@ -590,10 +590,10 @@ * Because of the general equivalence between {@code invokevirtual} * instructions and method handles produced by {@code findVirtual}, * if the class is {@code MethodHandle} and the name string is - * {@code invokeExact} or {@code invokeGeneric}, the resulting + * {@code invokeExact} or {@code invoke}, the resulting * method handle is equivalent to one produced by * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or - * {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker} + * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker} * with the same {@code type} argument. * * @param refc the class or interface from which the method is accessed @@ -1148,7 +1148,7 @@ * <li>an {@code Object[]} array containing more arguments * </ul> * <p> - * The invoker will behave like a call to {@link MethodHandle#invokeGeneric invokeGeneric} with + * The invoker will behave like a call to {@link MethodHandle#invoke invoke} with * the indicated {@code type}. * That is, if the target is exactly of the given {@code type}, it will behave * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType} @@ -1166,7 +1166,7 @@ * <p> * This method is equivalent to the following code (though it may be more efficient): * <p><blockquote><pre> -MethodHandle invoker = MethodHandles.genericInvoker(type); +MethodHandle invoker = MethodHandles.invoker(type); int spreadArgCount = type.parameterCount - objectArgCount; invoker = invoker.asSpreader(Object[].class, spreadArgCount); return invoker; @@ -1186,7 +1186,7 @@ /** * Produces a special <em>invoker method handle</em> which can be used to - * invoke any method handle of the given type, as if by {@code invokeExact}. + * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}. * The resulting invoker will have a type which is * exactly equal to the desired type, except that it will accept * an additional leading argument of type {@code MethodHandle}. @@ -1203,7 +1203,7 @@ * For example, to emulate an {@code invokeExact} call to a variable method * handle {@code M}, extract its type {@code T}, * look up the invoker method {@code X} for {@code T}, - * and call the invoker method, as {@code X.invokeGeneric(T, A...)}. + * and call the invoker method, as {@code X.invoke(T, A...)}. * (It would not work to call {@code X.invokeExact}, since the type {@code T} * is unknown.) * If spreading, collecting, or other argument transformations are required, @@ -1212,7 +1212,7 @@ * <p> * <em>(Note: The invoker method is not available via the Core Reflection API. * An attempt to call {@linkplain java.lang.reflect.Method#invoke Method.invoke} - * on the declared {@code invokeExact} or {@code invokeGeneric} method will raise an + * on the declared {@code invokeExact} or {@code invoke} method will raise an * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em> * <p> * This method throws no reflective or security exceptions. @@ -1226,20 +1226,20 @@ /** * Produces a special <em>invoker method handle</em> which can be used to - * invoke any method handle of the given type, as if by {@code invokeGeneric}. + * invoke any method handle compatible with the given type, as if by {@link MethodHandle#invoke invoke}. * 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> * Before invoking its target, the invoker will apply reference casts as - * necessary and unbox and widen primitive arguments, as if by {@link #convertArguments convertArguments}. - * The return value of the invoker will be an {@code Object} reference, - * boxing a primitive value if the original type returns a primitive, - * and always null if the original type returns void. + * necessary and box, unbox, or widen primitive values, as if by {@link MethodHandle#asType asType}. + * Similarly, the return value will be converted as necessary. + * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle}, + * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}. * <p> * This method is equivalent to the following code (though it may be more efficient): * <p><blockquote><pre> -publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type) +publicLookup().findVirtual(MethodHandle.class, "invoke", type) * </pre></blockquote> * <p> * This method throws no reflective or security exceptions. @@ -1247,8 +1247,17 @@ * @return a method handle suitable for invoking any method handle convertible to the given type */ static public + MethodHandle invoker(MethodType type) { + return type.invokers().generalInvoker(); + } + + /** + * <em>Temporary alias</em> for {@link #invoker}, for backward compatibility with some versions of JSR 292. + * @deprecated Will be removed for JSR 292 Proposed Final Draft. + */ + public static MethodHandle genericInvoker(MethodType type) { - return type.invokers().genericInvoker(); + return invoker(type); } /** @@ -2142,7 +2151,7 @@ * the given {@code target} on the incoming arguments, * and returning or throwing whatever the {@code target} * returns or throws. The invocation will be as if by - * {@code target.invokeGeneric}. + * {@code target.invoke}. * The target's type will be checked before the * instance is created, as if by a call to {@code asType}, * which may result in a {@code WrongMethodTypeException}.
--- a/jdk/src/share/classes/java/lang/invoke/MethodType.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java Thu May 12 19:27:33 2011 -0700 @@ -39,7 +39,7 @@ * matched between a method handle and all its callers, * and the JVM's operations enforce this matching at, specifically * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact} - * and {@link MethodHandle#invokeGeneric MethodHandle.invokeGeneric}, and during execution + * and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution * of {@code invokedynamic} instructions. * <p> * The structure is a return type accompanied by any number of parameter types. @@ -294,7 +294,7 @@ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}. * All parameters and the return type will be Object. * @param objectArgCount number of parameters - * @return a totally generic method type, given only its count of parameters + * @return a generally applicable method type, for all calls of the given argument count * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255 * @see #genericMethodType(int, boolean) */
--- a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java Thu May 12 19:27:33 2011 -0700 @@ -59,7 +59,7 @@ /*lazy*/ FromGeneric fromGeneric; // convert cs. w/o prims to with /*lazy*/ SpreadGeneric[] spreadGeneric; // expand one argument to many /*lazy*/ FilterGeneric filterGeneric; // convert argument(s) on the fly - /*lazy*/ MethodHandle genericInvoker; // hook for invokeGeneric + /*lazy*/ MethodHandle genericInvoker; // hook for inexact invoke public MethodType erasedType() { return erasedType; @@ -460,9 +460,9 @@ if (genericInvoker != null) return; try { // Trigger adapter creation. - genericInvoker = InvokeGeneric.genericInvokerOf(erasedType); + genericInvoker = InvokeGeneric.generalInvokerOf(erasedType); } catch (Exception ex) { - Error err = new InternalError("Exception while resolving invokeGeneric"); + Error err = new InternalError("Exception while resolving inexact invoke"); err.initCause(ex); throw err; }
--- a/jdk/src/share/classes/java/lang/invoke/package-info.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/src/share/classes/java/lang/invoke/package-info.java Thu May 12 19:27:33 2011 -0700 @@ -185,7 +185,7 @@ * The method handle constant produced for such a method behaves as if * it were created by {@link java.lang.invoke.MethodHandle#asVarargsCollector asVarargsCollector}. * In other words, the constant method handle will exhibit variable arity, - * when invoked via {@code invokeGeneric}. + * when invoked via {@code MethodHandle.invoke}. * On the other hand, its behavior with respect to {@code invokeExact} will be the same * as if the {@code varargs} bit were not set. * <p> @@ -243,7 +243,7 @@ * <li>optionally, one or more <a href="#args">additional static arguments</a> </li> * </ul> * The method handle is then applied to the other values as if by - * {@link java.lang.invoke.MethodHandle#invokeGeneric invokeGeneric}. + * {@link java.lang.invoke.MethodHandle#invoke MethodHandle.invoke}. * The returned result must be a {@link java.lang.invoke.CallSite CallSite} (or a subclass). * The type of the call site's target must be exactly equal to the type * derived from the dynamic call site's type descriptor and passed to @@ -251,7 +251,7 @@ * The call site then becomes permanently linked to the dynamic call site. * <p> * As long as each bootstrap method can be correctly invoked - * by <code>invokeGeneric</code>, its detailed type is arbitrary. + * by <code>MethodHandle.invoke</code>, its detailed type is arbitrary. * For example, the first argument could be {@code Object} * instead of {@code MethodHandles.Lookup}, and the return type * could also be {@code Object} instead of {@code CallSite}. @@ -272,7 +272,7 @@ * (i.e., a {@code CONSTANT_Class}, {@code CONSTANT_MethodType}, * or {@code CONSTANT_MethodHandle} argument cannot be linked) </li> * <li>the bootstrap method has the wrong arity, - * causing {@code invokeGeneric} to throw {@code WrongMethodTypeException} </li> + * causing {@code MethodHandle.invoke} to throw {@code WrongMethodTypeException} </li> * <li>the bootstrap method has a wrong argument or return type </li> * <li>the bootstrap method invocation completes abnormally </li> * <li>the result from the bootstrap invocation is not a reference to @@ -381,10 +381,10 @@ * those values will be passed as additional arguments to the method handle. * (Note that because there is a limit of 255 arguments to any method, * at most 252 extra arguments can be supplied.) - * The bootstrap method will be invoked as if by either {@code invokeGeneric} + * The bootstrap method will be invoked as if by either {@code MethodHandle.invoke} * or {@code invokeWithArguments}. (There is no way to tell the difference.) * <p> - * The normal argument conversion rules for {@code invokeGeneric} apply to all stacked arguments. + * The normal argument conversion rules for {@code MethodHandle.invoke} apply to all stacked arguments. * For example, if a pushed value is a primitive type, it may be converted to a reference by boxing conversion. * If the bootstrap method is a variable arity method (its modifier bit {@code 0x0080} is set), * then some or all of the arguments specified here may be collected into a trailing array parameter. @@ -419,8 +419,8 @@ * For example, the fourth argument could be {@code MethodHandle}, * if that is the type of the corresponding constant in * the {@code CONSTANT_InvokeDynamic} entry. - * In that case, the {@code invokeGeneric} call will pass the extra method handle - * constant as an {@code Object}, but the type matching machinery of {@code invokeGeneric} + * In that case, the {@code MethodHandle.invoke} call will pass the extra method handle + * constant as an {@code Object}, but the type matching machinery of {@code MethodHandle.invoke} * will cast the reference back to {@code MethodHandle} before invoking the bootstrap method. * (If a string constant were passed instead, by badly generated code, that cast would then fail, * resulting in a {@code BootstrapMethodError}.)
--- a/jdk/test/java/lang/invoke/InvokeGenericTest.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/test/java/lang/invoke/InvokeGenericTest.java Thu May 12 19:27:33 2011 -0700 @@ -24,7 +24,7 @@ */ /* @test - * @summary unit tests for java.lang.invoke.MethodHandle.invokeGeneric + * @summary unit tests for java.lang.invoke.MethodHandle.invoke * @compile -target 7 InvokeGenericTest.java * @run junit/othervm test.java.lang.invoke.InvokeGenericTest */ @@ -350,6 +350,18 @@ String[] args = { "one", "two" }; MethodHandle mh = callable(Object.class, String.class); Object res; List resl; + res = resl = (List) mh.invoke((String)args[0], (Object)args[1]); + //System.out.println(res); + assertEquals(Arrays.asList(args), res); + } + + @Test + public void testAlternateName() throws Throwable { + startTest("testAlternateName"); + countTest(); + String[] args = { "one", "two" }; + MethodHandle mh = callable(Object.class, String.class); + Object res; List resl; res = resl = (List) mh.invokeGeneric((String)args[0], (Object)args[1]); //System.out.println(res); assertEquals(Arrays.asList(args), res); @@ -388,15 +400,15 @@ try { switch (args.length) { case 0: - junk = target.invokeGeneric(); break; + junk = target.invoke(); break; case 1: - junk = target.invokeGeneric(args[0]); break; + junk = target.invoke(args[0]); break; case 2: - junk = target.invokeGeneric(args[0], args[1]); break; + junk = target.invoke(args[0], args[1]); break; case 3: - junk = target.invokeGeneric(args[0], args[1], args[2]); break; + junk = target.invoke(args[0], args[1], args[2]); break; case 4: - junk = target.invokeGeneric(args[0], args[1], args[2], args[3]); break; + junk = target.invoke(args[0], args[1], args[2], args[3]); break; default: junk = target.invokeWithArguments(args); break; } @@ -451,7 +463,7 @@ startTest("testReferenceConversions"); toString_MH = LOOKUP. findVirtual(Object.class, "toString", MethodType.methodType(String.class)); - String[] args = { "one", "two" }; + Object[] args = { "one", "two" }; for (MethodType type : allMethodTypes(2, Object.class, String.class, RandomInterface.class)) { testReferenceConversions(type, args); } @@ -463,7 +475,7 @@ MethodHandle tsdrop = MethodHandles.dropArguments(toString_MH, 1, type.parameterList()); mh = MethodHandles.foldArguments(tsdrop, mh); mh = mh.asType(type); - Object res = mh.invokeGeneric((String)args[0], (Object)args[1]); + Object res = mh.invoke((String)args[0], (Object)args[1]); //System.out.println(res); assertEquals(Arrays.asList(args).toString(), res); } @@ -473,10 +485,10 @@ public void testBoxConversions() throws Throwable { startTest("testBoxConversions"); countTest(); - Integer[] args = { 1, 2 }; + Object[] args = { 1, 2 }; MethodHandle mh = callable(Object.class, int.class); Object res; List resl; - res = resl = (List) mh.invokeGeneric((int)args[0], (Object)args[1]); + res = resl = (List) mh.invoke((int)args[0], (Object)args[1]); //System.out.println(res); assertEquals(Arrays.asList(args), res); }
--- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java Thu May 12 19:27:33 2011 -0700 @@ -170,8 +170,8 @@ mt = MethodType.methodType(java.util.List.class, Object[].class); mh = lookup.findStatic(java.util.Arrays.class, "asList", mt); assert(mh.isVarargsCollector()); -x = mh.invokeGeneric("one", "two"); -// invokeGeneric(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; +x = mh.invoke("one", "two"); +// invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; assert(x.equals(java.util.Arrays.asList("one","two"))); // mt is (Object,Object,Object)Object mt = MethodType.genericMethodType(3); @@ -199,12 +199,12 @@ MethodHandle asList = publicLookup() .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class)) .asVarargsCollector(Object[].class); -assertEquals("[]", asList.invokeGeneric().toString()); -assertEquals("[1]", asList.invokeGeneric(1).toString()); -assertEquals("[two, too]", asList.invokeGeneric("two", "too").toString()); +assertEquals("[]", asList.invoke().toString()); +assertEquals("[1]", asList.invoke(1).toString()); +assertEquals("[two, too]", asList.invoke("two", "too").toString()); Object[] argv = { "three", "thee", "tee" }; -assertEquals("[three, thee, tee]", asList.invokeGeneric(argv).toString()); -List ls = (List) asList.invokeGeneric((Object)argv); +assertEquals("[three, thee, tee]", asList.invoke(argv).toString()); +List ls = (List) asList.invoke((Object)argv); assertEquals(1, ls.size()); assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0))); }} @@ -218,9 +218,9 @@ .asVarargsCollector(Object[].class); MethodHandle mh = MethodHandles.exactInvoker(vamh.type()).bindTo(vamh); assert(vamh.type().equals(mh.type())); -assertEquals("[1, 2, 3]", vamh.invokeGeneric(1,2,3).toString()); +assertEquals("[1, 2, 3]", vamh.invoke(1,2,3).toString()); boolean failed = false; -try { mh.invokeGeneric(1,2,3); } +try { mh.invoke(1,2,3); } catch (WrongMethodTypeException ex) { failed = true; } assert(failed); {}
--- a/jdk/test/java/lang/invoke/MethodHandlesTest.java Fri May 06 18:09:33 2011 +0200 +++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java Thu May 12 19:27:33 2011 -0700 @@ -1780,7 +1780,7 @@ assertCalled("invokee", args); // generic invoker countTest(); - inv = MethodHandles.genericInvoker(type); + inv = MethodHandles.invoker(type); if (nargs <= 3) { calledLog.clear(); switch (nargs) {