src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java
author darcy
Mon, 09 Sep 2019 10:13:42 -0700
changeset 58054 ee230ad8cfef
parent 53018 8bf9268df0e2
permissions -rw-r--r--
8230723: Remove default constructors from java.lang and java.io Reviewed-by: bpb, rriggs
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     1
/*
58054
ee230ad8cfef 8230723: Remove default constructors from java.lang and java.io
darcy
parents: 53018
diff changeset
     2
 * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     4
 *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    10
 *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    15
 * accompanied this code).
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    16
 *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    20
 *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    23
 * questions.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    24
 */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    25
package java.lang.invoke;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    26
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    27
import sun.invoke.util.Wrapper;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    28
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    29
import static java.lang.invoke.MethodHandleNatives.mapLookupExceptionToError;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    30
import static java.util.Objects.requireNonNull;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    31
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    32
/**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    33
 * Bootstrap methods for dynamically-computed constants.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    34
 *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    35
 * <p>The bootstrap methods in this class will throw a
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    36
 * {@code NullPointerException} for any reference argument that is {@code null},
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    37
 * unless the argument is specified to be unused or specified to accept a
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    38
 * {@code null} value.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    39
 *
48878
2f265d2ac735 8196960: Exceptions in ConstantBootstrapsTest.java on SPARC
psandoz
parents: 48834
diff changeset
    40
 * @since 11
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    41
 */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    42
public final class ConstantBootstraps {
58054
ee230ad8cfef 8230723: Remove default constructors from java.lang and java.io
darcy
parents: 53018
diff changeset
    43
    /**
ee230ad8cfef 8230723: Remove default constructors from java.lang and java.io
darcy
parents: 53018
diff changeset
    44
     * Do not call.
ee230ad8cfef 8230723: Remove default constructors from java.lang and java.io
darcy
parents: 53018
diff changeset
    45
     */
ee230ad8cfef 8230723: Remove default constructors from java.lang and java.io
darcy
parents: 53018
diff changeset
    46
    @Deprecated(forRemoval=true, since="14")
ee230ad8cfef 8230723: Remove default constructors from java.lang and java.io
darcy
parents: 53018
diff changeset
    47
    public ConstantBootstraps() {}
ee230ad8cfef 8230723: Remove default constructors from java.lang and java.io
darcy
parents: 53018
diff changeset
    48
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    49
    // implements the upcall from the JVM, MethodHandleNatives.linkDynamicConstant:
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    50
    /*non-public*/
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    51
    static Object makeConstant(MethodHandle bootstrapMethod,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    52
                               // Callee information:
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    53
                               String name, Class<?> type,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    54
                               // Extra arguments for BSM, if any:
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    55
                               Object info,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    56
                               // Caller information:
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    57
                               Class<?> callerClass) {
49576
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    58
        // Restrict bootstrap methods to those whose first parameter is Lookup
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    59
        // The motivation here is, in the future, to possibly support BSMs
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    60
        // that do not accept the meta-data of lookup/name/type, thereby
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    61
        // allowing the co-opting of existing methods to be used as BSMs as
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    62
        // long as the static arguments can be passed as method arguments
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    63
        MethodType mt = bootstrapMethod.type();
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    64
        if (mt.parameterCount() < 2 ||
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    65
            !MethodHandles.Lookup.class.isAssignableFrom(mt.parameterType(0))) {
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    66
            throw new BootstrapMethodError(
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    67
                    "Invalid bootstrap method declared for resolving a dynamic constant: " + bootstrapMethod);
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    68
        }
535498e7602f 8199875: Require first parameter type of a condy bootstrap to be Lookup
psandoz
parents: 49242
diff changeset
    69
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    70
        // BSMI.invoke handles all type checking and exception translation.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    71
        // If type is not a reference type, the JVM is expecting a boxed
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    72
        // version, and will manage unboxing on the other side.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    73
        return BootstrapMethodInvoker.invoke(
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    74
                type, bootstrapMethod, name, type, info, callerClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    75
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    76
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    77
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    78
     * Returns a {@code null} object reference for the reference type specified
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    79
     * by {@code type}.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    80
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    81
     * @param lookup unused
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    82
     * @param name unused
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    83
     * @param type a reference type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    84
     * @return a {@code null} value
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    85
     * @throws IllegalArgumentException if {@code type} is not a reference type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    86
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    87
    public static Object nullConstant(MethodHandles.Lookup lookup, String name, Class<?> type) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    88
        if (requireNonNull(type).isPrimitive()) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    89
            throw new IllegalArgumentException(String.format("not reference: %s", type));
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    90
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    91
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    92
        return null;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    93
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    94
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    95
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    96
     * Returns a {@link Class} mirror for the primitive type whose type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    97
     * descriptor is specified by {@code name}.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    98
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    99
     * @param lookup unused
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   100
     * @param name the descriptor (JVMS 4.3) of the desired primitive type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   101
     * @param type the required result type (must be {@code Class.class})
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   102
     * @return the {@link Class} mirror
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   103
     * @throws IllegalArgumentException if the name is not a descriptor for a
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   104
     * primitive type or the type is not {@code Class.class}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   105
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   106
    public static Class<?> primitiveClass(MethodHandles.Lookup lookup, String name, Class<?> type) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   107
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   108
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   109
        if (type != Class.class) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   110
            throw new IllegalArgumentException();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   111
        }
53018
8bf9268df0e2 8215281: Use String.isEmpty() when applicable in java.base
redestad
parents: 49576
diff changeset
   112
        if (name.length() != 1) {
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   113
            throw new IllegalArgumentException(String.format("not primitive: %s", name));
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   114
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   115
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   116
        return Wrapper.forPrimitiveType(name.charAt(0)).primitiveType();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   117
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   118
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   119
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   120
     * Returns an {@code enum} constant of the type specified by {@code type}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   121
     * with the name specified by {@code name}.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   122
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   123
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   124
     * operation (normally stacked by the JVM)
49242
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   125
     * @param name the name of the constant to return, which must exactly match
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   126
     * an enum constant in the specified type.
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   127
     * @param type the {@code Class} object describing the enum type for which
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   128
     * a constant is to be returned
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   129
     * @param <E> The enum type for which a constant value is to be returned
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   130
     * @return the enum constant of the specified enum type with the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   131
     * specified name
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   132
     * @throws IllegalAccessError if the declaring class or the field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   133
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   134
     * @throws IllegalArgumentException if the specified enum type has
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   135
     * no constant with the specified name, or the specified
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   136
     * class object does not represent an enum type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   137
     * @see Enum#valueOf(Class, String)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   138
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   139
    public static <E extends Enum<E>> E enumConstant(MethodHandles.Lookup lookup, String name, Class<E> type) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   140
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   141
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   142
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   143
        validateClassAccess(lookup, type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   144
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   145
        return Enum.valueOf(type, name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   146
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   147
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   148
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   149
     * Returns the value of a static final field.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   150
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   151
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   152
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   153
     * @param name the name of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   154
     * @param type the type of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   155
     * @param declaringClass the class in which the field is declared
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   156
     * @return the value of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   157
     * @throws IllegalAccessError if the declaring class or the field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   158
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   159
     * @throws NoSuchFieldError if the specified field does not exist
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   160
     * @throws IncompatibleClassChangeError if the specified field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   161
     * {@code final}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   162
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   163
    public static Object getStaticFinal(MethodHandles.Lookup lookup, String name, Class<?> type,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   164
                                        Class<?> declaringClass) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   165
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   166
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   167
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   168
        requireNonNull(declaringClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   169
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   170
        MethodHandle mh;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   171
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   172
            mh = lookup.findStaticGetter(declaringClass, name, type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   173
            MemberName member = mh.internalMemberName();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   174
            if (!member.isFinal()) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   175
                throw new IncompatibleClassChangeError("not a final field: " + name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   176
            }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   177
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   178
        catch (ReflectiveOperationException ex) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   179
            throw mapLookupExceptionToError(ex);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   180
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   181
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   182
        // Since mh is a handle to a static field only instances of
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   183
        // VirtualMachineError are anticipated to be thrown, such as a
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   184
        // StackOverflowError or an InternalError from the j.l.invoke code
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   185
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   186
            return mh.invoke();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   187
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   188
        catch (RuntimeException | Error e) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   189
            throw e;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   190
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   191
        catch (Throwable e) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   192
            throw new LinkageError("Unexpected throwable", e);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   193
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   194
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   195
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   196
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   197
     * Returns the value of a static final field declared in the class which
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   198
     * is the same as the field's type (or, for primitive-valued fields,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   199
     * declared in the wrapper class.)  This is a simplified form of
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   200
     * {@link #getStaticFinal(MethodHandles.Lookup, String, Class, Class)}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   201
     * for the case where a class declares distinguished constant instances of
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   202
     * itself.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   203
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   204
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   205
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   206
     * @param name the name of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   207
     * @param type the type of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   208
     * @return the value of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   209
     * @throws IllegalAccessError if the declaring class or the field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   210
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   211
     * @throws NoSuchFieldError if the specified field does not exist
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   212
     * @throws IncompatibleClassChangeError if the specified field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   213
     * {@code final}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   214
     * @see #getStaticFinal(MethodHandles.Lookup, String, Class, Class)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   215
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   216
    public static Object getStaticFinal(MethodHandles.Lookup lookup, String name, Class<?> type) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   217
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   218
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   219
        Class<?> declaring = type.isPrimitive()
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   220
                             ? Wrapper.forPrimitiveType(type).wrapperType()
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   221
                             : type;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   222
        return getStaticFinal(lookup, name, type, declaring);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   223
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   224
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   225
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   226
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   227
     * Returns the result of invoking a method handle with the provided
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   228
     * arguments.
49242
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   229
     * <p>
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   230
     * This method behaves as if the method handle to be invoked is the result
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   231
     * of adapting the given method handle, via {@link MethodHandle#asType}, to
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   232
     * adjust the return type to the desired type.
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   233
     *
48990
9c006936068b 8198375: Passing 'null' value to lookup param of ConstantBootstraps.invoke does not throw NullPointerException
psandoz
parents: 48878
diff changeset
   234
     * @param lookup unused
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   235
     * @param name unused
49242
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   236
     * @param type the desired type of the value to be returned, which must be
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   237
     * compatible with the return type of the method handle
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   238
     * @param handle the method handle to be invoked
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   239
     * @param args the arguments to pass to the method handle, as if with
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   240
     * {@link MethodHandle#invokeWithArguments}.  Each argument may be
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   241
     * {@code null}.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   242
     * @return the result of invoking the method handle
49242
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   243
     * @throws WrongMethodTypeException if the handle's method type cannot be
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   244
     * adjusted to take the given number of arguments, or if the handle's return
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   245
     * type cannot be adjusted to the desired type
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   246
     * @throws ClassCastException if an argument or the result produced by
d2a2a80774e8 8198889: Clarify the throwing of exceptions from ConstantBootstraps.invoke
psandoz
parents: 48990
diff changeset
   247
     * invoking the handle cannot be converted by reference casting
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   248
     * @throws Throwable anything thrown by the method handle invocation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   249
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   250
    public static Object invoke(MethodHandles.Lookup lookup, String name, Class<?> type,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   251
                                MethodHandle handle, Object... args) throws Throwable {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   252
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   253
        requireNonNull(handle);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   254
        requireNonNull(args);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   255
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   256
        if (type != handle.type().returnType()) {
48834
19ef3f64bc10 8195694: ConstantBootstraps.invoke does not preserve variable arity
psandoz
parents: 48827
diff changeset
   257
            // Adjust the return type of the handle to be invoked while
19ef3f64bc10 8195694: ConstantBootstraps.invoke does not preserve variable arity
psandoz
parents: 48827
diff changeset
   258
            // preserving variable arity if present
19ef3f64bc10 8195694: ConstantBootstraps.invoke does not preserve variable arity
psandoz
parents: 48827
diff changeset
   259
            handle = handle.asType(handle.type().changeReturnType(type)).
19ef3f64bc10 8195694: ConstantBootstraps.invoke does not preserve variable arity
psandoz
parents: 48827
diff changeset
   260
                    withVarargs(handle.isVarargsCollector());
48827
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   261
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   262
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   263
        return handle.invokeWithArguments(args);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   264
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   265
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   266
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   267
     * Finds a {@link VarHandle} for an instance field.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   268
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   269
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   270
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   271
     * @param name the name of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   272
     * @param type the required result type (must be {@code Class<VarHandle>})
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   273
     * @param declaringClass the class in which the field is declared
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   274
     * @param fieldType the type of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   275
     * @return the {@link VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   276
     * @throws IllegalAccessError if the declaring class or the field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   277
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   278
     * @throws NoSuchFieldError if the specified field does not exist
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   279
     * @throws IllegalArgumentException if the type is not {@code VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   280
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   281
    public static VarHandle fieldVarHandle(MethodHandles.Lookup lookup, String name, Class<VarHandle> type,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   282
                                           Class<?> declaringClass, Class<?> fieldType) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   283
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   284
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   285
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   286
        requireNonNull(declaringClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   287
        requireNonNull(fieldType);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   288
        if (type != VarHandle.class) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   289
            throw new IllegalArgumentException();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   290
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   291
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   292
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   293
            return lookup.findVarHandle(declaringClass, name, fieldType);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   294
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   295
        catch (ReflectiveOperationException e) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   296
            throw mapLookupExceptionToError(e);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   297
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   298
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   299
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   300
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   301
     * Finds a {@link VarHandle} for a static field.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   302
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   303
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   304
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   305
     * @param name the name of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   306
     * @param type the required result type (must be {@code Class<VarHandle>})
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   307
     * @param declaringClass the class in which the field is declared
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   308
     * @param fieldType the type of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   309
     * @return the {@link VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   310
     * @throws IllegalAccessError if the declaring class or the field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   311
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   312
     * @throws NoSuchFieldError if the specified field does not exist
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   313
     * @throws IllegalArgumentException if the type is not {@code VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   314
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   315
    public static VarHandle staticFieldVarHandle(MethodHandles.Lookup lookup, String name, Class<VarHandle> type,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   316
                                                 Class<?> declaringClass, Class<?> fieldType) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   317
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   318
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   319
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   320
        requireNonNull(declaringClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   321
        requireNonNull(fieldType);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   322
        if (type != VarHandle.class) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   323
            throw new IllegalArgumentException();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   324
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   325
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   326
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   327
            return lookup.findStaticVarHandle(declaringClass, name, fieldType);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   328
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   329
        catch (ReflectiveOperationException e) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   330
            throw mapLookupExceptionToError(e);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   331
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   332
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   333
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   334
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   335
     * Finds a {@link VarHandle} for an array type.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   336
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   337
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   338
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   339
     * @param name unused
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   340
     * @param type the required result type (must be {@code Class<VarHandle>})
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   341
     * @param arrayClass the type of the array
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   342
     * @return the {@link VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   343
     * @throws IllegalAccessError if the component type of the array is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   344
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   345
     * @throws IllegalArgumentException if the type is not {@code VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   346
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   347
    public static VarHandle arrayVarHandle(MethodHandles.Lookup lookup, String name, Class<VarHandle> type,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   348
                                           Class<?> arrayClass) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   349
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   350
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   351
        requireNonNull(arrayClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   352
        if (type != VarHandle.class) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   353
            throw new IllegalArgumentException();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   354
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   355
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   356
        return MethodHandles.arrayElementVarHandle(validateClassAccess(lookup, arrayClass));
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   357
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   358
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   359
    private static <T> Class<T> validateClassAccess(MethodHandles.Lookup lookup, Class<T> type) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   360
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   361
            lookup.accessClass(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   362
            return type;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   363
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   364
        catch (ReflectiveOperationException ex) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   365
            throw mapLookupExceptionToError(ex);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   366
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   367
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   368
}