jdk/src/share/classes/java/dyn/MethodHandle.java
author jrose
Wed, 08 Sep 2010 18:40:23 -0700
changeset 7052 963a5baf2ba3
parent 7051 1c545d70a157
child 7554 8a0ad9757002
permissions -rw-r--r--
6980096: JSR 292 reflective lookup should throw checked exceptions Summary: Make NoAccessException be a checked exception. Also remove JavaMethodHandle. 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.
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
    40
 * (These transformations include conversion, insertion, deletion,
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
    41
 * substitution.  See the methods of this class and of {@link MethodHandles}.)
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    42
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    43
 * Method handles are strongly typed according to signature.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    44
 * 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
    45
 * A method handle must be invoked under a signature which matches
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    46
 * the method handle's own {@link MethodType method type}.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    47
 * <p>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    48
 * Every method handle confesses its type via the {@code type} accessor.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    49
 * 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
    50
 * 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
    51
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    52
 * Every method handle appears as an object containing a method named
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    53
 * {@code invoke}, whose signature exactly matches
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    54
 * the method handle's type.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    55
 * A Java method call expression, which compiles to an
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    56
 * {@code invokevirtual} instruction,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    57
 * can invoke this method from Java source code.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    58
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    59
 * 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
    60
 * 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
    61
 * (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
    62
 * via a {@code CONSTANT_NameAndType} constant pool entry.)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    63
 * The call looks within the receiver object for a method
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    64
 * named {@code invoke} of the intended method type.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    65
 * The call fails with a {@link WrongMethodTypeException}
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    66
 * if the method does not exist, even if there is an {@code invoke}
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    67
 * method of a closely similar signature.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    68
 * As with other kinds
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    69
 * 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
    70
 * 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
    71
 * 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
    72
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    73
 * 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
    74
 * 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
    75
 * 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
    76
 * 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
    77
 * 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
    78
 * (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
    79
 * methods, or in non-public classes, should generally be kept secret.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    80
 * They should not be passed to untrusted code.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    81
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    82
 * Bytecode in an extended JVM can directly call a method handle's
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    83
 * {@code invoke} from an {@code invokevirtual} instruction.
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    84
 * The receiver class type must be {@code MethodHandle} and the method name
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    85
 * must be {@code invoke}.  The signature of the invocation
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    86
 * (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
    87
 * of the target method.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    88
 * <p>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    89
 * Every {@code invoke} method always throws {@link Exception},
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    90
 * 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
    91
 * 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
    92
 * 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
    93
 * 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
    94
 * 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
    95
 * code, methods which perform method handle calls must either explicitly
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    96
 * throw {@code Exception}, or else must catch all checked exceptions locally.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
    97
 * <p>
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    98
 * Bytecode in an extended JVM can directly obtain a method handle
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
    99
 * for any accessible method from a {@code ldc} instruction
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   100
 * which refers to a {@code CONSTANT_Methodref} or
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   101
 * {@code CONSTANT_InterfaceMethodref} constant pool entry.
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   102
 * <p>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   103
 * All JVMs can also use a reflective API called {@code MethodHandles}
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   104
 * for creating and calling method handles.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   105
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   106
 * 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
   107
 * 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
   108
 * receiver argument, prepended before any other arguments.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   109
 * 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
   110
 * 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
   111
 * (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
   112
 * 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
   113
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   114
 * 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
   115
 * 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
   116
 * <p>
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   117
 * 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
   118
 * 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
   119
 * 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
   120
 * an {@code invokespecial} instruction to the same method.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   121
 * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   122
 * Here are some examples of usage:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   123
 * <p><blockquote><pre>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   124
Object x, y; String s; int i;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   125
MethodType mt; MethodHandle mh;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   126
MethodHandles.Lookup lookup = MethodHandles.lookup();
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   127
// mt is {(char,char) =&gt; String}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   128
mt = MethodType.methodType(String.class, char.class, char.class);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   129
mh = lookup.findVirtual(String.class, "replace", mt);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   130
// (Ljava/lang/String;CC)Ljava/lang/String;
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   131
s = mh.&lt;String&gt;invokeExact("daddy",'d','n');
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   132
assert(s.equals("nanny"));
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   133
// weakly typed invocation (using MHs.invoke)
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   134
s = (String) mh.invokeVarargs("sappy", 'p', 'v');
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   135
assert(s.equals("savvy"));
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   136
// mt is {Object[] =&gt; List}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   137
mt = MethodType.methodType(java.util.List.class, Object[].class);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   138
mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   139
// mt is {(Object,Object,Object) =&gt; Object}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   140
mt = MethodType.genericMethodType(3);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   141
mh = MethodHandles.collectArguments(mh, mt);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   142
// mt is {(Object,Object,Object) =&gt; Object}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   143
// (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
   144
x = mh.invokeExact((Object)1, (Object)2, (Object)3);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   145
assert(x.equals(java.util.Arrays.asList(1,2,3)));
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   146
// mt is { =&gt; int}
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   147
mt = MethodType.methodType(int.class);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   148
mh = lookup.findVirtual(java.util.List.class, "size", mt);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   149
// (Ljava/util/List;)I
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   150
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
   151
assert(i == 3);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   152
 * </pre></blockquote>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   153
 * 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
   154
 * 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
   155
 * 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
   156
 * 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
   157
 * (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
   158
 * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   159
 * <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
   160
 * 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
   161
 * 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
   162
 * Java types.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   163
 * <ol>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   164
 * <li>Method types range over all possible arities,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   165
 * from no arguments to an arbitrary number of arguments.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   166
 * 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
   167
 * <li>Method types can specify arguments of primitive types,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   168
 * which Java generic types cannot range over.</li>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   169
 * <li>Higher order functions over method handles (combinators) are
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   170
 * 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
   171
 * 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
   172
 * genericity with a Java type parameter.</li>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   173
 * </ol>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   174
 * Signature polymorphic methods in this class appear to be documented
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   175
 * 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
   176
 * merely a documentation convention.  These type parameters do
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   177
 * not play a role in type-checking method handle invocations.
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   178
 * <p>
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   179
 * 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
   180
 * fields, methods, and constructors can be represented directly
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   181
 * 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
   182
 * 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
   183
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   184
 * @see MethodType
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   185
 * @see MethodHandles
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   186
 * @author John Rose, JSR 292 EG
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   187
 */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   188
public abstract class MethodHandle
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   189
        // 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
   190
        // 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
   191
        extends MethodHandleImpl
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   192
        implements MethodHandleProvider
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   193
{
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   194
    private static Access IMPL_TOKEN = Access.getToken();
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   195
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   196
    // interface MethodHandle<R throws X extends Exception,A...>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   197
    // { 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
   198
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   199
    /**
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   200
     * Internal marker interface which distinguishes (to the Java compiler)
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   201
     * those methods which are signature polymorphic.
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   202
     */
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   203
    @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
   204
    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   205
    @interface PolymorphicSignature { }
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   206
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   207
    private MethodType type;
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   208
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   209
    /**
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   210
     * Report the type of this method handle.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   211
     * Every invocation of this method handle must exactly match this type.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   212
     * @return the method handle type
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   213
     */
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   214
    public final MethodType type() {
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   215
        return type;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   216
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   217
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   218
    /**
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   219
     * The constructor for MethodHandle may only be called by privileged code.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   220
     * Subclasses may be in other packages, but must possess
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   221
     * a token which they obtained from MH with a security check.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   222
     * @param token non-null object which proves access permission
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   223
     * @param type type (permanently assigned) of the new method handle
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   224
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   225
    protected MethodHandle(Access token, MethodType type) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   226
        super(token);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   227
        Access.check(token);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   228
        this.type = type;
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   229
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   230
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   231
    private void initType(MethodType type) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   232
        type.getClass();  // elicit NPE
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   233
        if (this.type != null)  throw new InternalError();
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   234
        this.type = type;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   235
    }
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   236
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   237
    static {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   238
        // This hack allows the implementation package special access to
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   239
        // 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
   240
        // of cached information useful to the implementation code.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   241
        MethodHandleImpl.setMethodHandleFriend(IMPL_TOKEN, new MethodHandleImpl.MethodHandleFriend() {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   242
            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
   243
        });
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   244
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   245
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   246
    /** The string of a direct method handle is the simple name of its target method.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   247
     * The string of an adapter or bound method handle is the string of its
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   248
     * target method handle.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   249
     * The string of a Java method handle is the string of its entry point method,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   250
     * unless the Java method handle overrides the toString method.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   251
     */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   252
    @Override
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   253
    public String toString() {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   254
        return MethodHandleImpl.getNameString(IMPL_TOKEN, this);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   255
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   256
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   257
    //// This is the "Method Handle Kernel API" discussed at the JVM Language Summit, 9/2009.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   258
    //// Implementations here currently delegate to statics in MethodHandles.  Some of those statics
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   259
    //// will be deprecated.  Others will be kept as "algorithms" to supply degrees of freedom
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   260
    //// not present in the Kernel API.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   261
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   262
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   263
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   264
     * 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
   265
     * The signature at the call site of {@code invokeExact} must
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   266
     * exactly match this method handle's {@code type}.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   267
     * No conversions are allowed on arguments or return values.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   268
     */
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   269
    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
   270
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   271
    // FIXME: remove this transitional form
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   272
    /** @deprecated transitional form defined in EDR but removed in PFD */
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   273
    public final native @PolymorphicSignature <R,A> R invoke(A... args) throws Throwable;
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   274
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
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   277
     * Invoke the method handle, allowing any caller signature,
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   278
     * and performing simple conversions for arguments and return types.
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   279
     * The signature at the call site of {@code invokeGeneric} must
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   280
     * have the same arity as this method handle's {@code type}.
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   281
     * <p>
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   282
     * If the call site signature exactly matches this method handle's {@code type},
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   283
     * the call proceeds as if by {@link #invokeExact}.
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   284
     * <p>
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   285
     * Otherwise, the call proceeds as if this method handle were first
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   286
     * adjusted by calling {@link #asType} to adjust this method handle
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   287
     * to the required type, and then the call proceeds as if by
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   288
     * {@link #invokeExact} on the adjusted method handle.
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   289
     */
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   290
    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
   291
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   292
    // ?? public final native @PolymorphicSignature <R,A,V> R invokeVarargs(A args, V[] varargs) throws Throwable;
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   293
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   294
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   295
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   296
     * Perform a varargs invocation, passing the arguments in the given array
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   297
     * to the method handle, as if via {@link #invokeGeneric} from a call site
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   298
     * 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
   299
     * of the argument array.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   300
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   301
     * The length of the arguments array must equal the parameter count
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   302
     * of the target's type.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   303
     * The arguments array is spread into separate arguments.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   304
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   305
     * In order to match the type of the target, the following argument
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   306
     * conversions are applied as necessary:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   307
     * <ul>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   308
     * <li>reference casting
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   309
     * <li>unboxing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   310
     * </ul>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   311
     * The following conversions are not applied:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   312
     * <ul>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   313
     * <li>primitive conversions (e.g., {@code byte} to {@code int}
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   314
     * <li>varargs conversions other than the initial spread
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   315
     * <li>any application-specific conversions (e.g., string to number)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   316
     * </ul>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   317
     * 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
   318
     * 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
   319
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   320
     * This call is equivalent to the following code:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   321
     * <p><blockquote><pre>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   322
     *   MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   323
     *   Object result = invoker.invokeExact(this, arguments);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   324
     * </pre></blockquote>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   325
     * @param arguments the arguments to pass to the target
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   326
     * @return the result returned by the target
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   327
     * @see MethodHandles#genericInvoker
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   328
     */
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   329
    public final Object invokeVarargs(Object... arguments) throws Throwable {
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   330
        int argc = arguments == null ? 0 : arguments.length;
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   331
        MethodType type = type();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   332
        if (argc <= 10) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   333
            MethodHandle invoker = MethodHandles.invokers(type).genericInvoker();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   334
            switch (argc) {
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   335
                case 0:  return invoker.invokeExact(this);
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   336
                case 1:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   337
                                    arguments[0]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   338
                case 2:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   339
                                    arguments[0], arguments[1]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   340
                case 3:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   341
                                    arguments[0], arguments[1], arguments[2]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   342
                case 4:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   343
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   344
                                    arguments[3]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   345
                case 5:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   346
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   347
                                    arguments[3], arguments[4]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   348
                case 6:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   349
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   350
                                    arguments[3], arguments[4], arguments[5]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   351
                case 7:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   352
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   353
                                    arguments[3], arguments[4], arguments[5],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   354
                                    arguments[6]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   355
                case 8:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   356
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   357
                                    arguments[3], arguments[4], arguments[5],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   358
                                    arguments[6], arguments[7]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   359
                case 9:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   360
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   361
                                    arguments[3], arguments[4], arguments[5],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   362
                                    arguments[6], arguments[7], arguments[8]);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   363
                case 10:  return invoker.invokeExact(this,
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   364
                                    arguments[0], arguments[1], arguments[2],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   365
                                    arguments[3], arguments[4], arguments[5],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   366
                                    arguments[6], arguments[7], arguments[8],
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   367
                                    arguments[9]);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   368
            }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   369
        }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   370
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   371
        // 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
   372
        MethodHandle invoker = MethodHandles.invokers(type).varargsInvoker(0);
5722
4ada807383c8 6939134: JSR 292 adjustments to method handle invocation
jrose
parents: 4537
diff changeset
   373
        return invoker.invokeExact(this, arguments);
4537
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   374
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   375
    /** Equivalent to {@code invokeVarargs(arguments.toArray())}. */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   376
    public final Object invokeVarargs(java.util.List<?> arguments) throws Throwable {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   377
        return invokeVarargs(arguments.toArray());
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   378
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   379
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   380
    /*  --- this is intentionally NOT a javadoc yet ---
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   381
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   382
     * Produce an adapter method handle which adapts the type of the
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   383
     * current method handle to a new type by pairwise argument conversion.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   384
     * The original type and new type must have the same number of arguments.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   385
     * The resulting method handle is guaranteed to confess a type
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   386
     * which is equal to the desired new type.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   387
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   388
     * 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
   389
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   390
     * The following conversions are applied as needed both to
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   391
     * arguments and return types.  Let T0 and T1 be the differing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   392
     * new and old parameter types (or old and new return types)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   393
     * for corresponding values passed by the new and old method types.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   394
     * Given those types T0, T1, one of the following conversions is applied
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   395
     * if possible:
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   396
     * <ul>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   397
     * <li>If T0 and T1 are references, and T1 is not an interface type,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   398
     *     then a cast to T1 is applied.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   399
     *     (The types do not need to be related in any particular way.)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   400
     * <li>If T0 and T1 are references, and T1 is an interface type,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   401
     *     then the value of type T0 is passed as a T1 without a cast.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   402
     *     (This treatment of interfaces follows the usage of the bytecode verifier.)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   403
     * <li>If T0 and T1 are primitives, then a Java casting
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   404
     *     conversion (JLS 5.5) is applied, if one exists.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   405
     * <li>If T0 and T1 are primitives and one is boolean,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   406
     *     the boolean is treated as a one-bit unsigned integer.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   407
     *     (This treatment follows the usage of the bytecode verifier.)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   408
     *     A conversion from another primitive type behaves as if
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   409
     *     it first converts to byte, and then masks all but the low bit.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   410
     * <li>If T0 is a primitive and T1 a reference, a boxing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   411
     *     conversion is applied if one exists, possibly followed by
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   412
     *     an reference conversion to a superclass.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   413
     *     T1 must be a wrapper class or a supertype of one.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   414
     *     If T1 is a wrapper class, T0 is converted if necessary
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   415
     *     to T1's primitive type by one of the preceding conversions.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   416
     *     Otherwise, T0 is boxed, and its wrapper converted to T1.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   417
     * <li>If T0 is a reference and T1 a primitive, an unboxing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   418
     *     conversion is applied if one exists, possibly preceded by
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   419
     *     a reference conversion to a wrapper class.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   420
     *     T0 must be a wrapper class or a supertype of one.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   421
     *     If T0 is a wrapper class, its primitive value is converted
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   422
     *     if necessary to T1 by one of the preceding conversions.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   423
     *     Otherwise, T0 is converted directly to the wrapper type for T1,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   424
     *     which is then unboxed.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   425
     * <li>If the return type T1 is void, any returned value is discarded
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   426
     * <li>If the return type T0 is void and T1 a reference, a null value is introduced.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   427
     * <li>If the return type T0 is void and T1 a primitive, a zero value is introduced.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   428
     * </ul>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   429
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   430
     */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   431
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   432
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   433
     * Produce an adapter method handle which adapts the type of the
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   434
     * current method handle to a new type by pairwise argument conversion.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   435
     * The original type and new type must have the same number of arguments.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   436
     * The resulting method handle is guaranteed to confess a type
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   437
     * which is equal to the desired new type.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   438
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   439
     * 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
   440
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   441
     * This method is equivalent to {@link MethodHandles#convertArguments}.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   442
     * @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
   443
     * @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
   444
     *           any necessary argument conversions, and arranges for any
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   445
     *           necessary return value conversions
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   446
     * @throws IllegalArgumentException if the conversion cannot be made
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   447
     * @see MethodHandles#convertArguments
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   448
     */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   449
    public final MethodHandle asType(MethodType newType) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   450
        return MethodHandles.convertArguments(this, newType);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   451
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   452
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   453
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   454
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   455
     * 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
   456
     * 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
   457
     * the same as the type of the target, except that all but the first
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   458
     * {@code keepPosArgs} parameters of the target's type are replaced
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   459
     * by a single array parameter of type {@code Object[]}.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   460
     * Thus, if {@code keepPosArgs} is zero, the adapter will take all
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   461
     * arguments in a single object array.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   462
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   463
     * When called, the adapter replaces a trailing array argument
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   464
     * 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
   465
     * (The order of the arguments is preserved.)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   466
     * They are converted pairwise by casting and/or unboxing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   467
     * (as if by {@link MethodHandles#convertArguments})
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   468
     * 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
   469
     * Finally the target is called.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   470
     * 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
   471
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   472
     * 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
   473
     * 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
   474
     * to the target method handle.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   475
     * (The array may also be null when zero elements are required.)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   476
     * @param keepPosArgs the number of leading positional arguments to preserve
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   477
     * @return a new method handle which spreads its final argument,
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   478
     *         before calling the original method handle
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   479
     * @throws IllegalArgumentException if target does not have at least
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   480
     *         {@code keepPosArgs} parameter types
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   481
     */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   482
    public final MethodHandle asSpreader(int keepPosArgs) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   483
        MethodType oldType = type();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   484
        int nargs = oldType.parameterCount();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   485
        MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   486
        newType = newType.insertParameterTypes(keepPosArgs, Object[].class);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   487
        return MethodHandles.spreadArguments(this, newType);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   488
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   489
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   490
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   491
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   492
     * 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
   493
     * 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
   494
     * the same as the type of the target, except that a single trailing
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   495
     * array parameter of type {@code Object[]} is replaced by
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   496
     * {@code spreadArrayArgs} parameters of type {@code Object}.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   497
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   498
     * When called, the adapter replaces its trailing {@code spreadArrayArgs}
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   499
     * arguments by a single new {@code Object} array, whose elements
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   500
     * comprise (in order) the replaced arguments.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   501
     * Finally the target is called.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   502
     * 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
   503
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   504
     * (The array may also be a shared constant when {@code spreadArrayArgs} is zero.)
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   505
     * @param spreadArrayArgs the number of arguments to spread from the trailing array
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   506
     * @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
   507
     *         into an array, before calling the original method handle
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   508
     * @throws IllegalArgumentException if the last argument of the target
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   509
     *         is not {@code Object[]}
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   510
     * @throws IllegalArgumentException if {@code spreadArrayArgs} is not
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   511
     *         a legal array size
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   512
     * @deprecated Provisional and unstable; use {@link MethodHandles#collectArguments}.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   513
     */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   514
    public final MethodHandle asCollector(int spreadArrayArgs) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   515
        MethodType oldType = type();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   516
        int nargs = oldType.parameterCount();
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   517
        MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   518
        newType = newType.insertParameterTypes(nargs-1, MethodType.genericMethodType(spreadArrayArgs).parameterArray());
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   519
        return MethodHandles.collectArguments(this, newType);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   520
    }
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   521
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   522
    /**
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   523
     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   524
     * Produce a method handle which binds the given argument
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   525
     * to the current method handle as <i>target</i>.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   526
     * The type of the bound handle will be
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   527
     * 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
   528
     * reference parameter will be omitted.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   529
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   530
     * 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
   531
     * 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
   532
     * also passed unchanged.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   533
     * 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
   534
     * <p>
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   535
     * 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
   536
     * type of the target.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   537
     * @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
   538
     * @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
   539
     *         into an array, before calling the original method handle
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   540
     * @throws IllegalArgumentException if the target does not have a
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   541
     *         leading parameter type that is a reference type
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   542
     * @throws ClassCastException if {@code x} cannot be converted
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   543
     *         to the leading parameter type of the target
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   544
     * @deprecated Provisional and unstable; use {@link MethodHandles#insertArguments}.
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   545
     */
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   546
    public final MethodHandle bindTo(Object x) {
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   547
        return MethodHandles.insertArguments(this, 0, x);
7c3c7f8d5195 6914665: update jdk code for JSR 292 (post 6858164)
jrose
parents: 2707
diff changeset
   548
    }
7051
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   549
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   550
    /** Implementation of {@link MethodHandleProvider}, which returns {@code this}. */
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   551
    public final MethodHandle asMethodHandle() { return this; }
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   552
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   553
    /** Implementation of {@link MethodHandleProvider}, which returns {@code this.asType(type)}. */
1c545d70a157 6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents: 5725
diff changeset
   554
    public final MethodHandle asMethodHandle(MethodType type) { return this.asType(type); }
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   555
}