jdk/src/share/classes/java/dyn/MethodHandle.java
author jrose
Sat, 30 Oct 2010 21:08:23 -0700
changeset 7555 a279ebc3b25c
parent 7554 8a0ad9757002
child 7556 4a5711d43948
permissions -rw-r--r--
6981777: implement JSR 292 EG adjustments from summer 2010 Reviewed-by: twisti
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     1
/*
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
     2
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     4
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4537
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4537
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    10
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    15
 * accompanied this code).
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    16
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4537
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4537
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4537
diff changeset
    23
 * questions.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    24
 */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    25
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    26
package java.dyn;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    27
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    28
//import sun.dyn.*;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    29
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    30
import sun.dyn.Access;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    31
import sun.dyn.MethodHandleImpl;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    32
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    33
import static java.dyn.MethodHandles.invokers;  // package-private API
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    34
import static sun.dyn.MemberName.newIllegalArgumentException;  // utility
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    35
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    36
/**
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    37
 * A method handle is a typed, directly executable reference to a method,
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    38
 * constructor, field, or similar low-level operation, with optional
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
    39
 * transformations of arguments or return values.
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    40
 * These transformations are quite general, and include such patterns as
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    41
 * {@linkplain #asType conversion},
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    42
 * {@linkplain #bindTo insertion},
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    43
 * {@linkplain java.dyn.MethodHandles#dropArguments deletion},
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    44
 * and {@linkplain java.dyn.MethodHandles#filterArguments substitution}.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    45
 * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    46
 * <em>Note: The super-class of MethodHandle is Object.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    47
 *     Any other super-class visible in the Reference Implementation
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    48
 *     will be removed before the Proposed Final Draft.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    49
 *     Also, the final version will not include any public or
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    50
 *     protected constructors.</em>
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    51
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    52
 * Method handles are strongly typed according to signature.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    53
 * They are not distinguished by method name or enclosing class.
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
    54
 * A method handle must be invoked under a signature which matches
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    55
 * the method handle's own {@linkplain MethodType method type}.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    56
 * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    57
 * Every method handle reports its type via the {@link #type type} accessor.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    58
 * The structure of this type is a series of classes, one of which is
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    59
 * the return type of the method (or {@code void.class} if none).
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    60
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    61
 * Every method handle appears as an object containing a method named
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    62
 * {@link #invokeExact invokeExact}, whose signature exactly matches
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    63
 * the method handle's type.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    64
 * A Java method call expression, which compiles to an
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    65
 * {@code invokevirtual} instruction,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    66
 * can invoke this method from Java source code.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    67
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    68
 * Every call to a method handle specifies an intended method type,
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    69
 * which must exactly match the type of the method handle.
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    70
 * (The type is specified in the {@code invokevirtual} instruction,
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    71
 * via a {@code CONSTANT_NameAndType} constant pool entry.)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    72
 * The call looks within the receiver object for a method
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    73
 * named {@code invokeExact} of the intended method type.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    74
 * The call fails with a {@link WrongMethodTypeException}
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    75
 * if the method does not exist, even if there is an {@code invokeExact}
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    76
 * method of a closely similar signature.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    77
 * As with other kinds
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    78
 * of methods in the JVM, signature matching during method linkage
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    79
 * is exact, and does not allow for language-level implicit conversions
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    80
 * such as {@code String} to {@code Object} or {@code short} to {@code int}.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    81
 * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    82
 * Each individual method handle also contains a method named
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    83
 * {@link #invokeGeneric invokeGeneric}, whose type is the same
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    84
 * as {@code invokeExact}, and is therefore also reported by
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    85
 * the {@link #type type} accessor.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    86
 * A call to {@code invokeGeneric} works the same as a call to
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    87
 * {@code invokeExact}, if the signature specified by the caller
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    88
 * exactly matches the method handle's own type.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    89
 * If there is a type mismatch, {@code invokeGeneric} attempts
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    90
 * to adjust the type of the target method handle
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    91
 * (as if by a call to {@link #asType asType})
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    92
 * to obtain an exactly invokable target.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    93
 * This allows a more powerful negotiation of method type
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    94
 * between caller and callee.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
    95
 * <p>
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    96
 * A method handle is an unrestricted capability to call a method.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    97
 * A method handle can be formed on a non-public method by a class
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    98
 * that has access to that method; the resulting handle can be used
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    99
 * in any place by any caller who receives a reference to it.  Thus, access
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   100
 * checking is performed when the method handle is created, not
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   101
 * (as in reflection) every time it is called.  Handles to non-public
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   102
 * methods, or in non-public classes, should generally be kept secret.
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   103
 * They should not be passed to untrusted code unless their use from
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   104
 * the untrusted code would be harmless.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   105
 * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   106
 * Bytecode in the JVM can directly call a method handle's
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   107
 * {@code invokeExact} method from an {@code invokevirtual} instruction.
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   108
 * The receiver class type must be {@code MethodHandle} and the method name
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   109
 * must be {@code invokeExact}.  The signature of the invocation
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   110
 * (after resolving symbolic type names) must exactly match the method type
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   111
 * of the target method.
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   112
 * Similarly, bytecode can directly call a method handle's {@code invokeGeneric}
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   113
 * method.  The signature of the invocation (after resolving symbolic type names)
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   114
 * must either exactly match the method type or be a valid argument to
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   115
 * the target's {@link #asType asType} method.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   116
 * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   117
 * Every {@code invokeExact} and {@code invokeGeneric} method always
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   118
 * throws {@link java.lang.Throwable Throwable},
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   119
 * which is to say that there is no static restriction on what a method handle
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   120
 * can throw.  Since the JVM does not distinguish between checked
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   121
 * and unchecked exceptions (other than by their class, of course),
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   122
 * there is no particular effect on bytecode shape from ascribing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   123
 * checked exceptions to method handle invocations.  But in Java source
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   124
 * code, methods which perform method handle calls must either explicitly
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   125
 * throw {@code java.lang.Throwable Throwable}, or else must catch all
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   126
 * throwables locally, rethrowing only those which are legal in the context,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   127
 * and wrapping ones which are illegal.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   128
 * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   129
 * Bytecode in the JVM can directly obtain a method handle
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   130
 * for any accessible method from a {@code ldc} instruction
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   131
 * which refers to a {@code CONSTANT_Methodref} or
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   132
 * {@code CONSTANT_InterfaceMethodref} constant pool entry.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   133
 * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   134
 * Java code can also use a reflective API called
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   135
 * {@link java.dyn.MethodHandles.Lookup MethodHandles.Lookup}
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   136
 * for creating and calling method handles.
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   137
 * For example, a static method handle can be obtained
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   138
 * from {@link java.dyn.MethodHandles.Lookup#findStatic Lookup.findStatic}.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   139
 * There are also bridge methods from Core Reflection API objects,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   140
 * such as {@link java.dyn.MethodHandles.Lookup#unreflect Lookup.ureflect}.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   141
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   142
 * A method reference may refer either to a static or non-static method.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   143
 * In the non-static case, the method handle type includes an explicit
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   144
 * receiver argument, prepended before any other arguments.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   145
 * In the method handle's type, the initial receiver argument is typed
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   146
 * according to the class under which the method was initially requested.
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   147
 * (E.g., if a non-static method handle is obtained via {@code ldc},
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   148
 * the type of the receiver is the class named in the constant pool entry.)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   149
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   150
 * When a method handle to a virtual method is invoked, the method is
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   151
 * always looked up in the receiver (that is, the first argument).
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   152
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   153
 * A non-virtual method handles to a specific virtual method implementation
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   154
 * can also be created.  These do not perform virtual lookup based on
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   155
 * receiver type.  Such a method handle simulates the effect of
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   156
 * an {@code invokespecial} instruction to the same method.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   157
 * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   158
 * Here are some examples of usage:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   159
 * <p><blockquote><pre>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   160
Object x, y; String s; int i;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   161
MethodType mt; MethodHandle mh;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   162
MethodHandles.Lookup lookup = MethodHandles.lookup();
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   163
// mt is {(char,char) =&gt; String}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   164
mt = MethodType.methodType(String.class, char.class, char.class);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   165
mh = lookup.findVirtual(String.class, "replace", mt);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   166
// (Ljava/lang/String;CC)Ljava/lang/String;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   167
s = mh.&lt;String&gt;invokeExact("daddy",'d','n');
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   168
assert(s.equals("nanny"));
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   169
// weakly typed invocation (using MHs.invoke)
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   170
s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   171
assert(s.equals("savvy"));
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   172
// mt is {Object[] =&gt; List}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   173
mt = MethodType.methodType(java.util.List.class, Object[].class);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   174
mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   175
// mt is {(Object,Object,Object) =&gt; Object}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   176
mt = MethodType.genericMethodType(3);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   177
mh = MethodHandles.collectArguments(mh, mt);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   178
// mt is {(Object,Object,Object) =&gt; Object}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   179
// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   180
x = mh.invokeExact((Object)1, (Object)2, (Object)3);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   181
assert(x.equals(java.util.Arrays.asList(1,2,3)));
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   182
// mt is { =&gt; int}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   183
mt = MethodType.methodType(int.class);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   184
mh = lookup.findVirtual(java.util.List.class, "size", mt);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   185
// (Ljava/util/List;)I
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   186
i = mh.&lt;int&gt;invokeExact(java.util.Arrays.asList(1,2,3));
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   187
assert(i == 3);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   188
 * </pre></blockquote>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   189
 * Each of the above calls generates a single invokevirtual instruction
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   190
 * with the name {@code invoke} and the type descriptors indicated in the comments.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   191
 * The argument types are taken directly from the actual arguments,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   192
 * while the return type is taken from the type parameter.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   193
 * (This type parameter may be a primitive, and it defaults to {@code Object}.)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   194
 * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   195
 * <em>A note on generic typing:</em>  Method handles do not represent
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   196
 * their function types in terms of Java parameterized (generic) types,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   197
 * because there are three mismatches between function types and parameterized
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   198
 * Java types.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   199
 * <ol>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   200
 * <li>Method types range over all possible arities,
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   201
 * from no arguments to up to 255 of arguments (a limit imposed by the JVM).
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   202
 * Generics are not variadic, and so cannot represent this.</li>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   203
 * <li>Method types can specify arguments of primitive types,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   204
 * which Java generic types cannot range over.</li>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   205
 * <li>Higher order functions over method handles (combinators) are
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   206
 * often generic across a wide range of function types, including
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   207
 * those of multiple arities.  It is impossible to represent such
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   208
 * genericity with a Java type parameter.</li>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   209
 * </ol>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   210
 * Signature polymorphic methods in this class appear to be documented
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   211
 * as having type parameters for return types and a parameter, but that is
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   212
 * merely a documentation convention.  These type parameters do
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   213
 * not play a role in type-checking method handle invocations.
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   214
 * <p>
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   215
 * Like classes and strings, method handles that correspond to accessible
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   216
 * fields, methods, and constructors can be represented directly
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   217
 * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   218
 * Loading such a constant causes the component classes of its type to be loaded as necessary.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   219
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   220
 * @see MethodType
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   221
 * @see MethodHandles
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   222
 * @author John Rose, JSR 292 EG
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   223
 */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   224
public abstract class MethodHandle
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   225
        // Note: This is an implementation inheritance hack, and will be removed
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   226
        // with a JVM change which moves the required hidden state onto this class.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   227
        extends MethodHandleImpl
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   228
{
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   229
    private static Access IMPL_TOKEN = Access.getToken();
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   230
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   231
    // interface MethodHandle<R throws X extends Exception,A...>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   232
    // { MethodType<R throws X,A...> type(); public R invokeExact(A...) throws X; }
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   233
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   234
    /**
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   235
     * Internal marker interface which distinguishes (to the Java compiler)
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   236
     * those methods which are signature polymorphic.
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   237
     */
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   238
    @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.TYPE})
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   239
    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   240
    @interface PolymorphicSignature { }
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   241
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   242
    private MethodType type;
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   243
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   244
    /**
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   245
     * Report the type of this method handle.
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   246
     * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   247
     * @return the method handle type
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   248
     */
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   249
    public final MethodType type() {
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   250
        return type;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   251
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   252
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   253
    /**
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   254
     * <em>CONSTRUCTOR WILL BE REMOVED FOR PFD:</em>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   255
     * Temporary constructor in early versions of the Reference Implementation.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   256
     * Method handle inheritance (if any) will be contained completely within
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   257
     * the {@code java.dyn} package.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   258
     */
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   259
    // The constructor for MethodHandle may only be called by privileged code.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   260
    // Subclasses may be in other packages, but must possess
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   261
    // a token which they obtained from MH with a security check.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   262
    // @param token non-null object which proves access permission
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   263
    // @param type type (permanently assigned) of the new method handle
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   264
    protected MethodHandle(Access token, MethodType type) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   265
        super(token);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   266
        Access.check(token);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   267
        this.type = type;
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   268
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   269
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   270
    private void initType(MethodType type) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   271
        type.getClass();  // elicit NPE
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   272
        if (this.type != null)  throw new InternalError();
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   273
        this.type = type;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   274
    }
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   275
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   276
    static {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   277
        // This hack allows the implementation package special access to
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   278
        // the internals of MethodHandle.  In particular, the MTImpl has all sorts
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   279
        // of cached information useful to the implementation code.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   280
        MethodHandleImpl.setMethodHandleFriend(IMPL_TOKEN, new MethodHandleImpl.MethodHandleFriend() {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   281
            public void initType(MethodHandle mh, MethodType type) { mh.initType(type); }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   282
        });
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   283
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   284
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   285
    /** Produce a printed representation that displays information about this call site
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   286
     *  that may be useful to the human reader.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   287
     */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   288
    @Override
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   289
    public String toString() {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   290
        return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   291
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   292
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   293
    /**
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   294
     * Invoke the method handle, allowing any caller signature, but requiring an exact signature match.
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   295
     * The signature at the call site of {@code invokeExact} must
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   296
     * exactly match this method handle's {@link #type type}.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   297
     * No conversions are allowed on arguments or return values.
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   298
     * @throws WrongMethodTypeException if the target's type is not identical with the caller's type signature
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   299
     * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   300
     */
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   301
    public final native @PolymorphicSignature <R,A> R invokeExact(A... args) throws Throwable;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   302
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   303
    /**
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   304
     * Invoke the method handle, allowing any caller signature,
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   305
     * and optionally performing conversions for arguments and return types.
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   306
     * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   307
     * If the call site signature exactly matches this method handle's {@link #type type},
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   308
     * the call proceeds as if by {@link #invokeExact invokeExact}.
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   309
     * <p>
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   310
     * Otherwise, the call proceeds as if this method handle were first
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   311
     * adjusted by calling {@link #asType asType} to adjust this method handle
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   312
     * to the required type, and then the call proceeds as if by
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   313
     * {@link #invokeExact invokeExact} on the adjusted method handle.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   314
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   315
     * There is no guarantee that the {@code asType} call is actually made.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   316
     * If the JVM can predict the results of making the call, it may perform
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   317
     * adaptations directly on the caller's arguments,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   318
     * and call the target method handle according to its own exact type.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   319
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   320
     * If the method handle is equipped with a
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   321
     * {@linkplain #withTypeHandler type handler}, the handler must produce
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   322
     * an entry point of the call site's exact type.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   323
     * Otherwise, the signature at the call site of {@code invokeGeneric} must
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   324
     * be a valid argument to the standard {@code asType} method.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   325
     * In particular, the caller must specify the same argument arity
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   326
     * as the callee's type.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   327
     * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's type signature
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   328
     * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   329
     */
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   330
    public final native @PolymorphicSignature <R,A> R invokeGeneric(A... args) throws Throwable;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   331
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   332
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   333
     * Perform a varargs invocation, passing the arguments in the given array
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   334
     * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   335
     * which mentions only the type {@code Object}, and whose arity is the length
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   336
     * of the argument array.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   337
     * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   338
     * Specifically, execution proceeds as if by the following steps,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   339
     * although the methods are not guaranteed to be called if the JVM
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   340
     * can predict their effects.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   341
     * <ul>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   342
     * <li>Determine the length of the argument array as {@code N}.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   343
     *     For a null reference, {@code N=0}. </li>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   344
     * <li>Determine the generic type {@code TN} of {@code N} arguments as
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   345
     *     as {@code TN=MethodType.genericMethodType(N)}.</li>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   346
     * <li>Force the original target method handle {@code MH0} to the
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   347
     *     required type, as {@code MH1 = MH0.asType(TN)}. </li>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   348
     * <li>Spread the array into {@code N} separate arguments {@code A0, ...}. </li>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   349
     * <li>Invoke the type-adjusted method handle on the unpacked arguments:
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   350
     *     MH1.invokeExact(A0, ...). </li>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   351
     * <li>Take the return value as an {@code Object} reference. </li>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   352
     * </ul>
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   353
     * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   354
     * Because of the action of the {@code asType} step, the following argument
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   355
     * conversions are applied as necessary:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   356
     * <ul>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   357
     * <li>reference casting
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   358
     * <li>unboxing
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   359
     * <li>widening primitive conversions
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   360
     * </ul>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   361
     * <p>
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   362
     * The result returned by the call is boxed if it is a primitive,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   363
     * or forced to null if the return type is void.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   364
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   365
     * This call is equivalent to the following code:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   366
     * <p><blockquote><pre>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   367
     * MethodHandle invoker = MethodHandles.varargsInvoker(this.type(), 0);
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   368
     * Object result = invoker.invokeExact(this, arguments);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   369
     * </pre></blockquote>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   370
     * @param arguments the arguments to pass to the target
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   371
     * @return the result returned by the target
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   372
     * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the arguments
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   373
     * @throws Throwable anything thrown by the target method invocation
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   374
     * @see MethodHandles#varargsInvoker
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   375
     */
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   376
    public final Object invokeWithArguments(Object... arguments) throws Throwable {
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   377
        int argc = arguments == null ? 0 : arguments.length;
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   378
        MethodType type = type();
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   379
        if (type.parameterCount() != argc) {
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   380
            // simulate invokeGeneric
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   381
            return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   382
        }
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   383
        if (argc <= 10) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   384
            MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   385
            switch (argc) {
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   386
                case 0:  return invoker.invokeExact(this);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   387
                case 1:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   388
                                    arguments[0]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   389
                case 2:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   390
                                    arguments[0], arguments[1]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   391
                case 3:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   392
                                    arguments[0], arguments[1], arguments[2]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   393
                case 4:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   394
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   395
                                    arguments[3]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   396
                case 5:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   397
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   398
                                    arguments[3], arguments[4]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   399
                case 6:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   400
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   401
                                    arguments[3], arguments[4], arguments[5]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   402
                case 7:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   403
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   404
                                    arguments[3], arguments[4], arguments[5],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   405
                                    arguments[6]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   406
                case 8:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   407
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   408
                                    arguments[3], arguments[4], arguments[5],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   409
                                    arguments[6], arguments[7]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   410
                case 9:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   411
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   412
                                    arguments[3], arguments[4], arguments[5],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   413
                                    arguments[6], arguments[7], arguments[8]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   414
                case 10:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   415
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   416
                                    arguments[3], arguments[4], arguments[5],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   417
                                    arguments[6], arguments[7], arguments[8],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   418
                                    arguments[9]);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   419
            }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   420
        }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   421
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   422
        // more than ten arguments get boxed in a varargs list:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   423
        MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   424
        return invoker.invokeExact(this, arguments);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   425
    }
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   426
    /** Equivalent to {@code invokeWithArguments(arguments.toArray())}. */
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   427
    public final Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   428
        return invokeWithArguments(arguments.toArray());
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   429
    }
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   430
    @Deprecated
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   431
    public final Object invokeVarargs(Object... arguments) throws Throwable {
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   432
        return invokeWithArguments(arguments);
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   433
    }
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   434
    @Deprecated
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   435
    public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable {
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   436
        return invokeWithArguments(arguments.toArray());
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   437
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   438
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   439
    /**
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   440
     * Produce an adapter method handle which adapts the type of the
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   441
     * current method handle to a new type
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   442
     * The resulting method handle is guaranteed to report a type
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   443
     * which is equal to the desired new type.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   444
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   445
     * If the original type and new type are equal, returns {@code this}.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   446
     * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   447
     * This method provides the crucial behavioral difference between
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   448
     * {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.  The two methods
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   449
     * perform the same steps when the caller's type descriptor is identical
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   450
     * with the callee's, but when the types differ, {@link #invokeGeneric invokeGeneric}
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   451
     * also calls {@code asType} (or some internal equivalent) in order
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   452
     * to match up the caller's and callee's types.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   453
     * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   454
     * This method is equivalent to {@link MethodHandles#convertArguments convertArguments},
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   455
     * except for method handles produced by {@link #withTypeHandler withTypeHandler},
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   456
     * in which case the specified type handler is used for calls to {@code asType}.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   457
     * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   458
     * Note that the default behavior of {@code asType} only performs
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   459
     * pairwise argument conversion and return value conversion.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   460
     * Because of this, unless the method handle has a type handler,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   461
     * the original type and new type must have the same number of arguments.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   462
     *
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   463
     * @param newType the expected type of the new method handle
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   464
     * @return a method handle which delegates to {@code this} after performing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   465
     *           any necessary argument conversions, and arranges for any
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   466
     *           necessary return value conversions
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   467
     * @throws WrongMethodTypeException if the conversion cannot be made
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   468
     * @see MethodHandles#convertArguments
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   469
     */
7554
8a0ad9757002 6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents: 7051
diff changeset
   470
    public MethodHandle asType(MethodType newType) {
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   471
        return MethodHandles.convertArguments(this, newType);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   472
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   473
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   474
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   475
     * Produce a method handle which adapts, as its <i>target</i>,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   476
     * the current method handle.  The type of the adapter will be
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   477
     * the same as the type of the target, except that the final
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   478
     * {@code arrayLength} parameters of the target's type are replaced
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   479
     * by a single array parameter of type {@code arrayType}.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   480
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   481
     * If the array element type differs from any of the corresponding
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   482
     * argument types on original target,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   483
     * the original target is adapted to take the array elements directly,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   484
     * as if by a call to {@link #asType asType}.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   485
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   486
     * When called, the adapter replaces a trailing array argument
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   487
     * by the array's elements, each as its own argument to the target.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   488
     * (The order of the arguments is preserved.)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   489
     * They are converted pairwise by casting and/or unboxing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   490
     * to the types of the trailing parameters of the target.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   491
     * Finally the target is called.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   492
     * What the target eventually returns is returned unchanged by the adapter.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   493
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   494
     * Before calling the target, the adapter verifies that the array
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   495
     * contains exactly enough elements to provide a correct argument count
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   496
     * to the target method handle.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   497
     * (The array may also be null when zero elements are required.)
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   498
     * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   499
     * @param arrayLength the number of arguments to spread from an incoming array argument
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   500
     * @return a new method handle which spreads its final array argument,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   501
     *         before calling the original method handle
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   502
     * @throws IllegalArgumentException if {@code arrayType} is not an array type
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   503
     * @throws IllegalArgumentException if target does not have at least
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   504
     *         {@code arrayLength} parameter types
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   505
     * @throws WrongMethodTypeException if the implied {@code asType} call fails
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   506
     */
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   507
    public final MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   508
        Class<?> arrayElement = arrayType.getComponentType();
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   509
        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   510
        MethodType oldType = type();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   511
        int nargs = oldType.parameterCount();
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   512
        if (nargs < arrayLength)  throw newIllegalArgumentException("bad spread array length");
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   513
        int keepPosArgs = nargs - arrayLength;
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   514
        MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   515
        newType = newType.insertParameterTypes(keepPosArgs, arrayElement);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   516
        return MethodHandles.spreadArguments(this, newType);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   517
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   518
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   519
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   520
     * Produce a method handle which adapts, as its <i>target</i>,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   521
     * the current method handle.  The type of the adapter will be
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   522
     * the same as the type of the target, except that a single trailing
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   523
     * parameter (usually of type {@code arrayType}) is replaced by
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   524
     * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   525
     * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   526
     * If the array type differs from the final argument type on original target,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   527
     * the original target is adapted to take the array type directly,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   528
     * as if by a call to {@link #asType asType}.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   529
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   530
     * When called, the adapter replaces its trailing {@code arrayLength}
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   531
     * arguments by a single new array of type {@code arrayType}, whose elements
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   532
     * comprise (in order) the replaced arguments.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   533
     * Finally the target is called.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   534
     * What the target eventually returns is returned unchanged by the adapter.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   535
     * <p>
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   536
     * (The array may also be a shared constant when {@code arrayLength} is zero.)
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   537
     * @param arrayType usually {@code Object[]}, the type of the array argument which will collect the arguments
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   538
     * @param arrayLength the number of arguments to collect into a new array argument
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   539
     * @return a new method handle which collects some trailing argument
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   540
     *         into an array, before calling the original method handle
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   541
     * @throws IllegalArgumentException if {@code arrayType} is not an array type
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   542
               or {@code arrayType} is not assignable to this method handle's trailing parameter type
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   543
     * @throws IllegalArgumentException if {@code arrayLength} is not
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   544
     *         a legal array size
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   545
     * @throws WrongMethodTypeException if the implied {@code asType} call fails
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   546
     */
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   547
    public final MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   548
        Class<?> arrayElement = arrayType.getComponentType();
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   549
        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   550
        MethodType oldType = type();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   551
        int nargs = oldType.parameterCount();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   552
        MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   553
        newType = newType.insertParameterTypes(nargs-1,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   554
                    java.util.Collections.<Class<?>>nCopies(arrayLength, arrayElement));
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   555
        return MethodHandles.collectArguments(this, newType);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   556
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   557
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   558
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   559
     * Produce a method handle which binds the given argument
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   560
     * to the current method handle as <i>target</i>.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   561
     * The type of the bound handle will be
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   562
     * the same as the type of the target, except that a single leading
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   563
     * reference parameter will be omitted.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   564
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   565
     * When called, the bound handle inserts the given value {@code x}
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   566
     * as a new leading argument to the target.  The other arguments are
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   567
     * also passed unchanged.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   568
     * What the target eventually returns is returned unchanged by the bound handle.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   569
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   570
     * The reference {@code x} must be convertible to the first parameter
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   571
     * type of the target.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   572
     * @param x  the value to bind to the first argument of the target
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   573
     * @return a new method handle which collects some trailing argument
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   574
     *         into an array, before calling the original method handle
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   575
     * @throws IllegalArgumentException if the target does not have a
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   576
     *         leading parameter type that is a reference type
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   577
     * @throws ClassCastException if {@code x} cannot be converted
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   578
     *         to the leading parameter type of the target
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   579
     * @see MethodHandles#insertArguments
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   580
     */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   581
    public final MethodHandle bindTo(Object x) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   582
        return MethodHandles.insertArguments(this, 0, x);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   583
    }
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   584
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   585
    /**
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   586
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   587
     * Create a new method handle with the same type as this one,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   588
     * but whose {@code asType} method invokes the given
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   589
     * {@code typeHandler} on this method handle,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   590
     * instead of the standard {@code MethodHandles.convertArguments}.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   591
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   592
     * The new method handle will have the same behavior as the
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   593
     * old one when invoked by {@code invokeExact}.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   594
     * For {@code invokeGeneric} calls which exactly match
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   595
     * the method type, the two method handles will also
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   596
     * have the same behavior.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   597
     * For other {@code invokeGeneric} calls, the {@code typeHandler}
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   598
     * will control the behavior of the new method handle.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   599
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   600
     * Thus, a method handle with an {@code asType} handler can
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   601
     * be configured to accept more than one arity of {@code invokeGeneric}
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   602
     * call, and potentially every possible arity.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   603
     * It can also be configured to supply default values for
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   604
     * optional arguments, when the caller does not specify them.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   605
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   606
     * The given method handle must take two arguments and return
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   607
     * one result.  The result it returns must be a method handle
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   608
     * of exactly the requested type.  If the result returned by
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   609
     * the target is null, a {@link NullPointerException} is thrown,
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   610
     * else if the type of the target does not exactly match
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   611
     * the requested type, a {@link WrongMethodTypeException} is thrown.
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   612
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   613
     * Therefore, the type handler is invoked as if by this code:
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   614
     * <blockquote><pre>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   615
     * MethodHandle target = this;      // original method handle
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   616
     * MethodHandle adapter = ...;      // adapted method handle
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   617
     * MethodType requestedType = ...;  // argument to asType()
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   618
     * if (type().equals(requestedType))
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   619
     *    return adapter;
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   620
     * MethodHandle result = (MethodHandle)
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   621
     *    typeHandler.invokeGeneric(target, requestedType);
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   622
     * if (!result.type().equals(requestedType))
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   623
     *    throw new WrongMethodTypeException();
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   624
     * return result;
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   625
     * </pre></blockquote>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   626
     * <p>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   627
     * For example, here is a list-making variable-arity method handle:
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   628
     * <blockquote><pre>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   629
MethodHandle makeEmptyList = MethodHandles.constant(List.class, Arrays.asList());
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   630
MethodHandle asList = lookup()
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   631
  .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   632
static MethodHandle collectingTypeHandler(MethodHandle base, MethodType newType) {
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   633
  return asList.asCollector(Object[].class, newType.parameterCount()).asType(newType);
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   634
}
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   635
MethodHandle collectingTypeHandler = lookup()
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   636
  .findStatic(lookup().lookupClass(), "collectingTypeHandler",
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   637
     methodType(MethodHandle.class, MethodHandle.class, MethodType.class));
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   638
MethodHandle makeAnyList = makeEmptyList.withTypeHandler(collectingTypeHandler);
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   639
7555
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   640
System.out.println(makeAnyList.invokeGeneric()); // prints []
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   641
System.out.println(makeAnyList.invokeGeneric(1)); // prints [1]
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   642
System.out.println(makeAnyList.invokeGeneric("two", "too")); // prints [two, too]
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   643
     * <pre><blockquote>
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   644
     */
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   645
    public MethodHandle withTypeHandler(MethodHandle typeHandler) {
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   646
        return MethodHandles.withTypeHandler(this, typeHandler);
a279ebc3b25c 6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents: 7554
diff changeset
   647
    }
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   648
}