src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java
author psandoz
Wed, 31 Jan 2018 11:20:36 -0800
changeset 48827 8772acd913e5
child 48834 19ef3f64bc10
permissions -rw-r--r--
8187742: Minimal set of bootstrap methods for constant dynamic Reviewed-by: jrose, forax Contributed-by: brian.goetz@oracle.com, paul.sandoz@oracle.com
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
/*
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
     2
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
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
 *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    40
 * @since 10
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 {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    43
    // implements the upcall from the JVM, MethodHandleNatives.linkDynamicConstant:
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    44
    /*non-public*/
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    45
    static Object makeConstant(MethodHandle bootstrapMethod,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    46
                               // Callee information:
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    47
                               String name, Class<?> type,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    48
                               // Extra arguments for BSM, if any:
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    49
                               Object info,
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    50
                               // Caller information:
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    51
                               Class<?> callerClass) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    52
        // BSMI.invoke handles all type checking and exception translation.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    53
        // 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
    54
        // version, and will manage unboxing on the other side.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    55
        return BootstrapMethodInvoker.invoke(
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    56
                type, bootstrapMethod, name, type, info, callerClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    57
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    58
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    59
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    60
     * 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
    61
     * by {@code type}.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    62
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    63
     * @param lookup unused
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    64
     * @param name unused
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    65
     * @param type a reference type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    66
     * @return a {@code null} value
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    67
     * @throws IllegalArgumentException if {@code type} is not a reference type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    68
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    69
    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
    70
        if (requireNonNull(type).isPrimitive()) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    71
            throw new IllegalArgumentException(String.format("not reference: %s", type));
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    72
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    73
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    74
        return null;
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 {@link Class} mirror for the primitive type whose type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    79
     * descriptor is specified by {@code name}.
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 the descriptor (JVMS 4.3) of the desired primitive type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    83
     * @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
    84
     * @return the {@link Class} mirror
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    85
     * @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
    86
     * primitive type or the type is not {@code Class.class}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    87
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    88
    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
    89
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    90
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    91
        if (type != Class.class) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    92
            throw new IllegalArgumentException();
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
        if (name.length() == 0 || name.length() > 1) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    95
            throw new IllegalArgumentException(String.format("not primitive: %s", name));
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    96
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    97
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    98
        return Wrapper.forPrimitiveType(name.charAt(0)).primitiveType();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
    99
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   100
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   101
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   102
     * 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
   103
     * with the name specified by {@code name}.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   104
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   105
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   106
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   107
     * @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
   108
     * a constant is to be returned
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   109
     * @param name the name of the constant to return, which must exactly match
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   110
     * an enum constant in the specified type.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   111
     * @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
   112
     * @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
   113
     * specified name
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   114
     * @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
   115
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   116
     * @throws IllegalArgumentException if the specified enum type has
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   117
     * no constant with the specified name, or the specified
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   118
     * class object does not represent an enum type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   119
     * @see Enum#valueOf(Class, String)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   120
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   121
    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
   122
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   123
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   124
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   125
        validateClassAccess(lookup, type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   126
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   127
        return Enum.valueOf(type, name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   128
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   129
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   130
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   131
     * Returns the value of a static final field.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   132
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   133
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   134
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   135
     * @param name the name of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   136
     * @param type the type of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   137
     * @param declaringClass the class in which the field is declared
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   138
     * @return the value of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   139
     * @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
   140
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   141
     * @throws NoSuchFieldError if the specified field does not exist
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   142
     * @throws IncompatibleClassChangeError if the specified field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   143
     * {@code final}
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
    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
   146
                                        Class<?> declaringClass) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   147
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   148
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   149
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   150
        requireNonNull(declaringClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   151
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   152
        MethodHandle mh;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   153
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   154
            mh = lookup.findStaticGetter(declaringClass, name, type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   155
            MemberName member = mh.internalMemberName();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   156
            if (!member.isFinal()) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   157
                throw new IncompatibleClassChangeError("not a final field: " + name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   158
            }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   159
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   160
        catch (ReflectiveOperationException ex) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   161
            throw mapLookupExceptionToError(ex);
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
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   164
        // 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
   165
        // VirtualMachineError are anticipated to be thrown, such as a
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   166
        // StackOverflowError or an InternalError from the j.l.invoke code
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   167
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   168
            return mh.invoke();
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
        catch (RuntimeException | Error e) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   171
            throw e;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   172
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   173
        catch (Throwable e) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   174
            throw new LinkageError("Unexpected throwable", e);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   175
        }
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
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   179
     * 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
   180
     * 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
   181
     * 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
   182
     * {@link #getStaticFinal(MethodHandles.Lookup, String, Class, Class)}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   183
     * 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
   184
     * itself.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   185
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   186
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   187
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   188
     * @param name the name of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   189
     * @param type the type of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   190
     * @return the value of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   191
     * @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
   192
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   193
     * @throws NoSuchFieldError if the specified field does not exist
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   194
     * @throws IncompatibleClassChangeError if the specified field is not
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   195
     * {@code final}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   196
     * @see #getStaticFinal(MethodHandles.Lookup, String, Class, Class)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   197
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   198
    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
   199
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   200
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   201
        Class<?> declaring = type.isPrimitive()
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   202
                             ? Wrapper.forPrimitiveType(type).wrapperType()
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   203
                             : type;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   204
        return getStaticFinal(lookup, name, type, declaring);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   205
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   206
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   207
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   208
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   209
     * 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
   210
     * arguments.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   211
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   212
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   213
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   214
     * @param name unused
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   215
     * @param type the type of the value to be returned, which must be
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   216
     * compatible with the return type of the method handle
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   217
     * @param handle the method handle to be invoked
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   218
     * @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
   219
     * {@link MethodHandle#invokeWithArguments}.  Each argument may be
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   220
     * {@code null}.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   221
     * @return the result of invoking the method handle
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   222
     * @throws WrongMethodTypeException if the handle's return type cannot be
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   223
     * adjusted to the desired type
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   224
     * @throws ClassCastException if an argument cannot be converted by
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   225
     * reference casting
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   226
     * @throws Throwable anything thrown by the method handle invocation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   227
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   228
    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
   229
                                MethodHandle handle, Object... args) throws Throwable {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   230
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   231
        requireNonNull(handle);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   232
        requireNonNull(args);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   233
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   234
        if (type != handle.type().returnType()) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   235
            handle = handle.asType(handle.type().changeReturnType(type));
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   236
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   237
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   238
        return handle.invokeWithArguments(args);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   239
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   240
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   241
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   242
     * Finds a {@link VarHandle} for an instance field.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   243
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   244
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   245
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   246
     * @param name the name of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   247
     * @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
   248
     * @param declaringClass the class in which the field is declared
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   249
     * @param fieldType the type of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   250
     * @return the {@link VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   251
     * @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
   252
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   253
     * @throws NoSuchFieldError if the specified field does not exist
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   254
     * @throws IllegalArgumentException if the type is not {@code VarHandle}
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
    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
   257
                                           Class<?> declaringClass, Class<?> fieldType) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   258
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   259
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   260
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   261
        requireNonNull(declaringClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   262
        requireNonNull(fieldType);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   263
        if (type != VarHandle.class) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   264
            throw new IllegalArgumentException();
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
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   268
            return lookup.findVarHandle(declaringClass, name, fieldType);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   269
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   270
        catch (ReflectiveOperationException e) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   271
            throw mapLookupExceptionToError(e);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   272
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   273
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   274
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   275
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   276
     * Finds a {@link VarHandle} for a static field.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   277
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   278
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   279
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   280
     * @param name the name of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   281
     * @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
   282
     * @param declaringClass the class in which the field is declared
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   283
     * @param fieldType the type of the field
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   284
     * @return the {@link VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   285
     * @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
   286
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   287
     * @throws NoSuchFieldError if the specified field does not exist
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   288
     * @throws IllegalArgumentException if the type is not {@code VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   289
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   290
    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
   291
                                                 Class<?> declaringClass, Class<?> fieldType) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   292
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   293
        requireNonNull(name);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   294
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   295
        requireNonNull(declaringClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   296
        requireNonNull(fieldType);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   297
        if (type != VarHandle.class) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   298
            throw new IllegalArgumentException();
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
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   302
            return lookup.findStaticVarHandle(declaringClass, name, fieldType);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   303
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   304
        catch (ReflectiveOperationException e) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   305
            throw mapLookupExceptionToError(e);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   306
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   307
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   308
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   309
    /**
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   310
     * Finds a {@link VarHandle} for an array type.
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   311
     *
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   312
     * @param lookup the lookup context describing the class performing the
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   313
     * operation (normally stacked by the JVM)
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   314
     * @param name unused
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   315
     * @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
   316
     * @param arrayClass the type of the array
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   317
     * @return the {@link VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   318
     * @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
   319
     * accessible to the class performing the operation
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   320
     * @throws IllegalArgumentException if the type is not {@code VarHandle}
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   321
     */
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   322
    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
   323
                                           Class<?> arrayClass) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   324
        requireNonNull(lookup);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   325
        requireNonNull(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   326
        requireNonNull(arrayClass);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   327
        if (type != VarHandle.class) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   328
            throw new IllegalArgumentException();
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   329
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   330
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   331
        return MethodHandles.arrayElementVarHandle(validateClassAccess(lookup, arrayClass));
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
    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
   335
        try {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   336
            lookup.accessClass(type);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   337
            return type;
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   338
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   339
        catch (ReflectiveOperationException ex) {
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   340
            throw mapLookupExceptionToError(ex);
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   341
        }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   342
    }
8772acd913e5 8187742: Minimal set of bootstrap methods for constant dynamic
psandoz
parents:
diff changeset
   343
}