jdk/test/java/lang/invoke/RevealDirectTest.java
author serb
Tue, 12 Nov 2013 20:24:25 +0400
changeset 21596 0e3a39f29dbc
parent 20535 cc85c8626435
child 30820 0d4717a011d3
permissions -rw-r--r--
8027696: Incorrect copyright header in the tests Reviewed-by: alanb, malenkov, mullan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
19804
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
     1
/*
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
     2
 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
     4
 *
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
21596
0e3a39f29dbc 8027696: Incorrect copyright header in the tests
serb
parents: 20535
diff changeset
     7
 * published by the Free Software Foundation.
19804
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
     8
 *
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    13
 * accompanied this code).
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    14
 *
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    18
 *
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    21
 * questions.
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    22
 */
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    23
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    24
/*
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    25
 * @test
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    26
 * @summary verify Lookup.revealDirect on a variety of input handles
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    27
 * @compile -XDignore.symbol.file RevealDirectTest.java
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    28
 * @run junit/othervm -ea -esa test.java.lang.invoke.RevealDirectTest
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    29
 *
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    30
 * @test
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    31
 * @summary verify Lookup.revealDirect on a variety of input handles, with security manager
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    32
 * @run main/othervm/policy=jtreg.security.policy/secure=java.lang.SecurityManager -ea -esa test.java.lang.invoke.RevealDirectTest
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    33
 */
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    34
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    35
/* To run manually:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    36
 * $ $JAVA8X_HOME/bin/javac -cp $JUNIT4_JAR -d ../../../.. -XDignore.symbol.file RevealDirectTest.java
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    37
 * $ $JAVA8X_HOME/bin/java  -cp $JUNIT4_JAR:../../../.. -ea -esa org.junit.runner.JUnitCore test.java.lang.invoke.RevealDirectTest
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    38
 * $ $JAVA8X_HOME/bin/java  -cp $JUNIT4_JAR:../../../.. -ea -esa    -Djava.security.manager test.java.lang.invoke.RevealDirectTest
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    39
 */
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    40
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    41
package test.java.lang.invoke;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    42
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    43
import java.lang.reflect.*;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    44
import java.lang.invoke.*;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    45
import static java.lang.invoke.MethodHandles.*;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    46
import static java.lang.invoke.MethodType.*;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    47
import static java.lang.invoke.MethodHandleInfo.*;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    48
import java.util.*;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    49
import static org.junit.Assert.*;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    50
import org.junit.*;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    51
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    52
public class RevealDirectTest {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    53
    public static void main(String... av) throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    54
        // Run the @Test methods explicitly, in case we don't want to use the JUnitCore driver.
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    55
        // This appears to be necessary when running with a security manager.
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    56
        Throwable fail = null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    57
        for (Method test : RevealDirectTest.class.getDeclaredMethods()) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    58
            if (!test.isAnnotationPresent(Test.class))  continue;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    59
            try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    60
                test.invoke(new RevealDirectTest());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    61
            } catch (Throwable ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    62
                if (ex instanceof InvocationTargetException)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    63
                    ex = ex.getCause();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    64
                if (fail == null)  fail = ex;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    65
                System.out.println("Testcase: "+test.getName()
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    66
                                   +"("+test.getDeclaringClass().getName()
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    67
                                   +"):\tCaused an ERROR");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    68
                System.out.println(ex);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    69
                ex.printStackTrace(System.out);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    70
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    71
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    72
        if (fail != null)  throw fail;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    73
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    74
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    75
    public interface SimpleSuperInterface {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    76
        public abstract int getInt();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    77
        public static void printAll(String... args) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    78
            System.out.println(Arrays.toString(args));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    79
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    80
        public int NICE_CONSTANT = 42;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    81
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    82
    public interface SimpleInterface extends SimpleSuperInterface {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    83
        default float getFloat() { return getInt(); }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    84
        public static void printAll(String[] args) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    85
            System.out.println(Arrays.toString(args));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    86
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    87
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    88
    public static class Simple implements SimpleInterface, Cloneable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    89
        public int intField;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    90
        public final int finalField;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    91
        private static String stringField;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    92
        public int getInt() { return NICE_CONSTANT; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    93
        private static Number getNum() { return 804; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    94
        public Simple clone() {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    95
            try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    96
                return (Simple) super.clone();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    97
            } catch (CloneNotSupportedException ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    98
                throw new RuntimeException(ex);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
    99
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   100
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   101
        Simple() { finalField = -NICE_CONSTANT; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   102
        private static Lookup localLookup() { return lookup(); }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   103
        private static List<Member> members() { return getMembers(lookup().lookupClass()); };
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   104
    }
20535
cc85c8626435 8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents: 19804
diff changeset
   105
    static class Nestmate {
cc85c8626435 8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents: 19804
diff changeset
   106
        private static Lookup localLookup() { return lookup(); }
cc85c8626435 8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents: 19804
diff changeset
   107
    }
19804
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   108
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   109
    static boolean VERBOSE = false;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   110
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   111
    @Test public void testSimple() throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   112
        if (VERBOSE)  System.out.println("@Test testSimple");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   113
        testOnMembers("testSimple", Simple.members(), Simple.localLookup());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   114
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   115
    @Test public void testPublicLookup() throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   116
        if (VERBOSE)  System.out.println("@Test testPublicLookup");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   117
        List<Member> mems = publicOnly(Simple.members());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   118
        Lookup pubLookup = publicLookup(), privLookup = Simple.localLookup();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   119
        testOnMembers("testPublicLookup/1", mems, pubLookup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   120
        // reveal using publicLookup:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   121
        testOnMembers("testPublicLookup/2", mems, privLookup, pubLookup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   122
        // lookup using publicLookup, but reveal using private:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   123
        testOnMembers("testPublicLookup/3", mems, pubLookup, privLookup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   124
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   125
    @Test public void testPublicLookupNegative() throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   126
        if (VERBOSE)  System.out.println("@Test testPublicLookupNegative");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   127
        List<Member> mems = nonPublicOnly(Simple.members());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   128
        Lookup pubLookup = publicLookup(), privLookup = Simple.localLookup();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   129
        testOnMembersNoLookup("testPublicLookupNegative/1", mems, pubLookup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   130
        testOnMembersNoReveal("testPublicLookupNegative/2", mems, privLookup, pubLookup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   131
        testOnMembersNoReflect("testPublicLookupNegative/3", mems, privLookup, pubLookup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   132
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   133
    @Test public void testJavaLangClass() throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   134
        if (VERBOSE)  System.out.println("@Test testJavaLangClass");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   135
        List<Member> mems = callerSensitive(false, publicOnly(getMembers(Class.class)));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   136
        mems = limit(20, mems);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   137
        testOnMembers("testJavaLangClass", mems, Simple.localLookup());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   138
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   139
    @Test public void testCallerSensitive() throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   140
        if (VERBOSE)  System.out.println("@Test testCallerSensitive");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   141
        List<Member> mems = union(getMembers(MethodHandles.class, "lookup"),
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   142
                                  getMembers(Method.class, "invoke"),
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   143
                                  getMembers(Field.class, "get", "set", "getLong"),
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   144
                                  getMembers(Class.class));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   145
        mems = callerSensitive(true, publicOnly(mems));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   146
        mems = limit(10, mems);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   147
        testOnMembers("testCallerSensitive", mems, Simple.localLookup());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   148
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   149
    @Test public void testCallerSensitiveNegative() throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   150
        if (VERBOSE)  System.out.println("@Test testCallerSensitiveNegative");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   151
        List<Member> mems = union(getMembers(MethodHandles.class, "lookup"),
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   152
                                  getMembers(Class.class, "forName"),
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   153
                                  getMembers(Method.class, "invoke"));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   154
        mems = callerSensitive(true, publicOnly(mems));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   155
        // CS methods cannot be looked up with publicLookup
20535
cc85c8626435 8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents: 19804
diff changeset
   156
        testOnMembersNoLookup("testCallerSensitiveNegative/1", mems, publicLookup());
cc85c8626435 8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents: 19804
diff changeset
   157
        // CS methods have to be revealed with a matching lookupClass
cc85c8626435 8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents: 19804
diff changeset
   158
        testOnMembersNoReveal("testCallerSensitiveNegative/2", mems, Simple.localLookup(), publicLookup());
cc85c8626435 8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents: 19804
diff changeset
   159
        testOnMembersNoReveal("testCallerSensitiveNegative/3", mems, Simple.localLookup(), Nestmate.localLookup());
19804
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   160
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   161
    @Test public void testMethodHandleNatives() throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   162
        if (VERBOSE)  System.out.println("@Test testMethodHandleNatives");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   163
        List<Member> mems = getMembers(MethodHandle.class, "invoke", "invokeExact");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   164
        testOnMembers("testMethodHandleNatives", mems, Simple.localLookup());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   165
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   166
    @Test public void testMethodHandleInvokes() throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   167
        if (VERBOSE)  System.out.println("@Test testMethodHandleInvokes");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   168
        List<MethodType> types = new ArrayList<>();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   169
        Class<?>[] someParamTypes = { void.class, int.class, Object.class, Object[].class };
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   170
        for (Class<?> rt : someParamTypes) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   171
            for (Class<?> p0 : someParamTypes) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   172
                if (p0 == void.class) { types.add(methodType(rt)); continue; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   173
                for (Class<?> p1 : someParamTypes) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   174
                    if (p1 == void.class) { types.add(methodType(rt, p0)); continue; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   175
                    for (Class<?> p2 : someParamTypes) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   176
                        if (p2 == void.class) { types.add(methodType(rt, p0, p1)); continue; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   177
                        types.add(methodType(rt, p0, p1, p2));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   178
                    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   179
                }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   180
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   181
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   182
        List<Member> mems = union(getPolyMembers(MethodHandle.class, "invoke", types),
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   183
                                  getPolyMembers(MethodHandle.class, "invokeExact", types));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   184
        testOnMembers("testMethodHandleInvokes/1", mems, Simple.localLookup());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   185
        testOnMembers("testMethodHandleInvokes/2", mems, publicLookup());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   186
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   187
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   188
    static List<Member> getPolyMembers(Class<?> cls, String name, List<MethodType> types) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   189
        assert(cls == MethodHandle.class);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   190
        ArrayList<Member> mems = new ArrayList<>();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   191
        for (MethodType type : types) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   192
            mems.add(new SignaturePolymorphicMethod(name, type));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   193
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   194
        return mems;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   195
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   196
    static List<Member> getMembers(Class<?> cls) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   197
        return getMembers(cls, (String[]) null);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   198
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   199
    static List<Member> getMembers(Class<?> cls, String... onlyNames) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   200
        List<String> names = (onlyNames == null || onlyNames.length == 0 ? null : Arrays.asList(onlyNames));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   201
        ArrayList<Member> res = new ArrayList<>();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   202
        for (Class<?> sup : getSupers(cls)) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   203
            res.addAll(getDeclaredMembers(sup, "getDeclaredFields"));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   204
            res.addAll(getDeclaredMembers(sup, "getDeclaredMethods"));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   205
            res.addAll(getDeclaredMembers(sup, "getDeclaredConstructors"));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   206
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   207
        res = new ArrayList<>(new LinkedHashSet<>(res));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   208
        for (int i = 0; i < res.size(); i++) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   209
            Member mem = res.get(i);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   210
            if (!canBeReached(mem, cls) ||
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   211
                res.indexOf(mem) != i ||
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   212
                mem.isSynthetic() ||
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   213
                (names != null && !names.contains(mem.getName()))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   214
                ) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   215
                res.remove(i--);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   216
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   217
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   218
        return res;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   219
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   220
    static List<Class<?>> getSupers(Class<?> cls) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   221
        ArrayList<Class<?>> res = new ArrayList<>();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   222
        ArrayList<Class<?>> intfs = new ArrayList<>();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   223
        for (Class<?> sup = cls; sup != null; sup = sup.getSuperclass()) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   224
            res.add(sup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   225
            for (Class<?> intf : cls.getInterfaces()) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   226
                if (!intfs.contains(intf))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   227
                    intfs.add(intf);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   228
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   229
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   230
        for (int i = 0; i < intfs.size(); i++) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   231
            for (Class<?> intf : intfs.get(i).getInterfaces()) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   232
                if (!intfs.contains(intf))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   233
                    intfs.add(intf);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   234
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   235
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   236
        res.addAll(intfs);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   237
        //System.out.println("getSupers => "+res);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   238
        return res;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   239
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   240
    static boolean hasSM() {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   241
        return (System.getSecurityManager() != null);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   242
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   243
    static List<Member> getDeclaredMembers(Class<?> cls, String accessor) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   244
        Member[] mems = {};
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   245
        Method getter = getMethod(Class.class, accessor);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   246
        if (hasSM()) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   247
            try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   248
                mems = (Member[]) invokeMethod(getter, cls);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   249
            } catch (SecurityException ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   250
                //if (VERBOSE)  ex.printStackTrace();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   251
                accessor = accessor.replace("Declared", "");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   252
                getter = getMethod(Class.class, accessor);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   253
                if (VERBOSE)  System.out.println("replaced accessor: "+getter);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   254
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   255
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   256
        if (mems.length == 0) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   257
            try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   258
                mems = (Member[]) invokeMethod(getter, cls);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   259
            } catch (SecurityException ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   260
                ex.printStackTrace();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   261
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   262
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   263
        if (VERBOSE)  System.out.println(accessor+" "+cls.getName()+" => "+mems.length+" members");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   264
        return Arrays.asList(mems);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   265
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   266
    static Method getMethod(Class<?> cls, String name) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   267
        try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   268
            return cls.getMethod(name);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   269
        } catch (ReflectiveOperationException ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   270
            throw new AssertionError(ex);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   271
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   272
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   273
    static Object invokeMethod(Method m, Object recv, Object... args) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   274
        try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   275
            return m.invoke(recv, args);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   276
        } catch (InvocationTargetException ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   277
            Throwable ex2 = ex.getCause();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   278
            if (ex2 instanceof RuntimeException)  throw (RuntimeException) ex2;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   279
            if (ex2 instanceof Error)  throw (Error) ex2;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   280
            throw new AssertionError(ex);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   281
        } catch (ReflectiveOperationException ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   282
            throw new AssertionError(ex);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   283
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   284
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   285
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   286
    static List<Member> limit(int len, List<Member> mems) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   287
        if (mems.size() <= len)  return mems;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   288
        return mems.subList(0, len);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   289
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   290
    @SafeVarargs
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   291
    static List<Member> union(List<Member> mems, List<Member>... mem2s) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   292
        for (List<Member> mem2 : mem2s) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   293
            for (Member m : mem2) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   294
                if (!mems.contains(m))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   295
                    mems.add(m);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   296
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   297
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   298
        return mems;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   299
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   300
    static List<Member> callerSensitive(boolean cond, List<Member> members) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   301
        for (Iterator<Member> i = members.iterator(); i.hasNext(); ) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   302
            Member mem = i.next();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   303
            if (isCallerSensitive(mem) != cond)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   304
                i.remove();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   305
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   306
        if (members.isEmpty())  throw new AssertionError("trivial result");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   307
        return members;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   308
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   309
    static boolean isCallerSensitive(Member mem) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   310
        if (!(mem instanceof AnnotatedElement))  return false;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   311
        AnnotatedElement ae = (AnnotatedElement) mem;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   312
        if (CS_CLASS != null)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   313
            return ae.isAnnotationPresent(sun.reflect.CallerSensitive.class);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   314
        for (java.lang.annotation.Annotation a : ae.getDeclaredAnnotations()) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   315
            if (a.toString().contains(".CallerSensitive"))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   316
                return true;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   317
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   318
        return false;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   319
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   320
    static final Class<?> CS_CLASS;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   321
    static {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   322
        Class<?> c = null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   323
        try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   324
            c = sun.reflect.CallerSensitive.class;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   325
        } catch (SecurityException | LinkageError ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   326
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   327
        CS_CLASS = c;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   328
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   329
    static List<Member> publicOnly(List<Member> members) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   330
        return removeMods(members, Modifier.PUBLIC, 0);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   331
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   332
    static List<Member> nonPublicOnly(List<Member> members) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   333
        return removeMods(members, Modifier.PUBLIC, -1);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   334
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   335
    static List<Member> removeMods(List<Member> members, int mask, int bits) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   336
        int publicMods = (mask & Modifier.PUBLIC);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   337
        members = new ArrayList<>(members);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   338
        for (Iterator<Member> i = members.iterator(); i.hasNext(); ) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   339
            Member mem = i.next();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   340
            int mods = mem.getModifiers();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   341
            if ((publicMods & mods) != 0 &&
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   342
                (publicMods & mem.getDeclaringClass().getModifiers()) == 0)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   343
                mods -= publicMods;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   344
            if ((mods & mask) == (bits & mask))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   345
                i.remove();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   346
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   347
        return members;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   348
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   349
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   350
    void testOnMembers(String tname, List<Member> mems, Lookup lookup, Lookup... lookups) throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   351
        if (VERBOSE)  System.out.println("testOnMembers "+mems);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   352
        Lookup revLookup = (lookups.length > 0) ? lookups[0] : null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   353
        if (revLookup == null)  revLookup = lookup;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   354
        Lookup refLookup = (lookups.length > 1) ? lookups[1] : null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   355
        if (refLookup == null)  refLookup = lookup;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   356
        assert(lookups.length <= 2);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   357
        testOnMembersImpl(tname, mems, lookup, revLookup, refLookup, NO_FAIL);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   358
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   359
    void testOnMembersNoLookup(String tname, List<Member> mems, Lookup lookup) throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   360
        if (VERBOSE)  System.out.println("testOnMembersNoLookup "+mems);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   361
        testOnMembersImpl(tname, mems, lookup, null, null, FAIL_LOOKUP);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   362
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   363
    void testOnMembersNoReveal(String tname, List<Member> mems,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   364
                               Lookup lookup, Lookup negLookup) throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   365
        if (VERBOSE)  System.out.println("testOnMembersNoReveal "+mems);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   366
        testOnMembersImpl(tname, mems, lookup, negLookup, null, FAIL_REVEAL);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   367
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   368
    void testOnMembersNoReflect(String tname, List<Member> mems,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   369
                                Lookup lookup, Lookup negLookup) throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   370
        if (VERBOSE)  System.out.println("testOnMembersNoReflect "+mems);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   371
        testOnMembersImpl(tname, mems, lookup, lookup, negLookup, FAIL_REFLECT);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   372
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   373
    void testOnMembersImpl(String tname, List<Member> mems,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   374
                           Lookup lookup,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   375
                           Lookup revLookup,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   376
                           Lookup refLookup,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   377
                           int failureMode) throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   378
        Throwable fail = null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   379
        int failCount = 0;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   380
        failureModeCounts = new int[FAIL_MODE_COUNT];
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   381
        long tm0 = System.currentTimeMillis();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   382
        for (Member mem : mems) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   383
            try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   384
                testWithMember(mem, lookup, revLookup, refLookup, failureMode);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   385
            } catch (Throwable ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   386
                if (fail == null)  fail = ex;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   387
                if (++failCount > 10) { System.out.println("*** FAIL: too many failures"); break; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   388
                System.out.println("*** FAIL: "+mem+" => "+ex);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   389
                if (VERBOSE)  ex.printStackTrace(System.out);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   390
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   391
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   392
        long tm1 = System.currentTimeMillis();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   393
        System.out.printf("@Test %s executed %s tests in %d ms",
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   394
                          tname, testKinds(failureModeCounts), (tm1-tm0)).println();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   395
        if (fail != null)  throw fail;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   396
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   397
    static String testKinds(int[] modes) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   398
        int pos = modes[0], neg = -pos;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   399
        for (int n : modes)  neg += n;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   400
        if (neg == 0)  return pos + " positive";
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   401
        String negs = "";
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   402
        for (int n : modes)  negs += "/"+n;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   403
        negs = negs.replaceFirst("/"+pos+"/", "");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   404
        negs += " negative";
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   405
        if (pos == 0)  return negs;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   406
        return pos + " positive, " + negs;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   407
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   408
    static class SignaturePolymorphicMethod implements Member {  // non-reflected instance of MH.invoke*
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   409
        final String name;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   410
        final MethodType type;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   411
        SignaturePolymorphicMethod(String name, MethodType type) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   412
            this.name = name;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   413
            this.type = type;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   414
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   415
        public String toString() {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   416
            String typeStr = type.toString();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   417
            if (isVarArgs())  typeStr = typeStr.replaceFirst("\\[\\])$", "...)");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   418
            return (Modifier.toString(getModifiers())
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   419
                    +typeStr.substring(0, typeStr.indexOf('('))+" "
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   420
                    +getDeclaringClass().getTypeName()+"."
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   421
                    +getName()+typeStr.substring(typeStr.indexOf('(')));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   422
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   423
        public boolean equals(Object x) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   424
            return (x instanceof SignaturePolymorphicMethod && equals((SignaturePolymorphicMethod)x));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   425
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   426
        public boolean equals(SignaturePolymorphicMethod that) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   427
            return this.name.equals(that.name) && this.type.equals(that.type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   428
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   429
        public int hashCode() {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   430
            return name.hashCode() * 31 + type.hashCode();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   431
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   432
        public Class<?> getDeclaringClass() { return MethodHandle.class; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   433
        public String getName() { return name; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   434
        public MethodType getMethodType() { return type; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   435
        public int getModifiers() { return Modifier.PUBLIC | Modifier.FINAL | Modifier.NATIVE | SYNTHETIC; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   436
        public boolean isVarArgs() { return Modifier.isTransient(getModifiers()); }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   437
        public boolean isSynthetic() { return true; }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   438
        public Class<?> getReturnType() { return type.returnType(); }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   439
        public Class<?>[] getParameterTypes() { return type.parameterArray(); }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   440
        static final int SYNTHETIC = 0x00001000;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   441
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   442
    static class UnreflectResult {  // a tuple
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   443
        final MethodHandle mh;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   444
        final Throwable ex;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   445
        final byte kind;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   446
        final Member mem;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   447
        final int var;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   448
        UnreflectResult(MethodHandle mh, byte kind, Member mem, int var) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   449
            this.mh = mh;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   450
            this.ex = null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   451
            this.kind = kind;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   452
            this.mem = mem;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   453
            this.var = var;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   454
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   455
        UnreflectResult(Throwable ex, byte kind, Member mem, int var) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   456
            this.mh = null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   457
            this.ex = ex;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   458
            this.kind = kind;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   459
            this.mem = mem;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   460
            this.var = var;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   461
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   462
        public String toString() {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   463
            return toInfoString()+"/v"+var;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   464
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   465
        public String toInfoString() {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   466
            return String.format("%s %s.%s:%s", MethodHandleInfo.referenceKindToString(kind),
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   467
                                 mem.getDeclaringClass().getName(), name(mem), type(mem, kind));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   468
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   469
        static String name(Member mem) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   470
            if (mem instanceof Constructor)  return "<init>";
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   471
            return mem.getName();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   472
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   473
        static MethodType type(Member mem, byte kind) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   474
            if (mem instanceof Field) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   475
                Class<?> type = ((Field)mem).getType();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   476
                if (kind == REF_putStatic || kind == REF_putField)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   477
                    return methodType(void.class, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   478
                return methodType(type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   479
            } else if (mem instanceof SignaturePolymorphicMethod) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   480
                return ((SignaturePolymorphicMethod)mem).getMethodType();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   481
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   482
            Class<?>[] params = ((Executable)mem).getParameterTypes();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   483
            if (mem instanceof Constructor)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   484
                return methodType(void.class, params);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   485
            Class<?> type = ((Method)mem).getReturnType();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   486
            return methodType(type, params);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   487
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   488
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   489
    static UnreflectResult unreflectMember(Lookup lookup, Member mem, int variation) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   490
        byte[] refKind = {0};
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   491
        try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   492
            return unreflectMemberOrThrow(lookup, mem, variation, refKind);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   493
        } catch (ReflectiveOperationException|SecurityException ex) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   494
            return new UnreflectResult(ex, refKind[0], mem, variation);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   495
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   496
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   497
    static UnreflectResult unreflectMemberOrThrow(Lookup lookup, Member mem, int variation,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   498
                                                  byte[] refKind) throws ReflectiveOperationException {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   499
        Class<?> cls = lookup.lookupClass();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   500
        Class<?> defc = mem.getDeclaringClass();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   501
        String   name = mem.getName();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   502
        int      mods = mem.getModifiers();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   503
        boolean isStatic = Modifier.isStatic(mods);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   504
        MethodHandle mh = null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   505
        byte kind = 0;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   506
        if (mem instanceof Method) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   507
            Method m = (Method) mem;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   508
            MethodType type = methodType(m.getReturnType(), m.getParameterTypes());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   509
            boolean canBeSpecial = (!isStatic &&
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   510
                                    (lookup.lookupModes() & Modifier.PRIVATE) != 0 &&
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   511
                                    defc.isAssignableFrom(cls) &&
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   512
                                    (!defc.isInterface() || Arrays.asList(cls.getInterfaces()).contains(defc)));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   513
            if (variation >= 2)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   514
                kind = REF_invokeSpecial;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   515
            else if (isStatic)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   516
                kind = REF_invokeStatic;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   517
            else if (defc.isInterface())
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   518
                kind = REF_invokeInterface;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   519
            else
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   520
                kind = REF_invokeVirtual;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   521
            refKind[0] = kind;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   522
            switch (variation) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   523
            case 0:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   524
                mh = lookup.unreflect(m);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   525
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   526
            case 1:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   527
                if (defc == MethodHandle.class &&
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   528
                    !isStatic &&
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   529
                    m.isVarArgs() &&
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   530
                    Modifier.isFinal(mods) &&
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   531
                    Modifier.isNative(mods)) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   532
                    break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   533
                }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   534
                if (isStatic)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   535
                    mh = lookup.findStatic(defc, name, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   536
                else
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   537
                    mh = lookup.findVirtual(defc, name, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   538
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   539
            case 2:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   540
                if (!canBeSpecial)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   541
                    break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   542
                mh = lookup.unreflectSpecial(m, lookup.lookupClass());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   543
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   544
            case 3:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   545
                if (!canBeSpecial)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   546
                    break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   547
                mh = lookup.findSpecial(defc, name, type, lookup.lookupClass());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   548
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   549
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   550
        } else if (mem instanceof SignaturePolymorphicMethod) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   551
            SignaturePolymorphicMethod m = (SignaturePolymorphicMethod) mem;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   552
            MethodType type = methodType(m.getReturnType(), m.getParameterTypes());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   553
            kind = REF_invokeVirtual;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   554
            refKind[0] = kind;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   555
            switch (variation) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   556
            case 0:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   557
                mh = lookup.findVirtual(defc, name, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   558
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   559
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   560
        } else if (mem instanceof Constructor) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   561
            name = "<init>";  // not used
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   562
            Constructor<?> m = (Constructor<?>) mem;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   563
            MethodType type = methodType(void.class, m.getParameterTypes());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   564
            kind = REF_newInvokeSpecial;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   565
            refKind[0] = kind;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   566
            switch (variation) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   567
            case 0:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   568
                mh = lookup.unreflectConstructor(m);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   569
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   570
            case 1:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   571
                mh = lookup.findConstructor(defc, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   572
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   573
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   574
        } else if (mem instanceof Field) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   575
            Field m = (Field) mem;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   576
            Class<?> type = m.getType();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   577
            boolean canHaveSetter = !Modifier.isFinal(mods);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   578
            if (variation >= 2)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   579
                kind = (byte)(isStatic ? REF_putStatic : REF_putField);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   580
            else
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   581
                kind = (byte)(isStatic ? REF_getStatic : REF_getField);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   582
            refKind[0] = kind;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   583
            switch (variation) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   584
            case 0:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   585
                mh = lookup.unreflectGetter(m);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   586
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   587
            case 1:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   588
                if (isStatic)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   589
                    mh = lookup.findStaticGetter(defc, name, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   590
                else
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   591
                    mh = lookup.findGetter(defc, name, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   592
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   593
            case 3:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   594
                if (!canHaveSetter)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   595
                    break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   596
                mh = lookup.unreflectSetter(m);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   597
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   598
            case 2:
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   599
                if (!canHaveSetter)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   600
                    break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   601
                if (isStatic)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   602
                    mh = lookup.findStaticSetter(defc, name, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   603
                else
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   604
                    mh = lookup.findSetter(defc, name, type);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   605
                break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   606
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   607
        } else {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   608
            throw new IllegalArgumentException(String.valueOf(mem));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   609
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   610
        if (mh == null)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   611
            // ran out of valid variations; return null to caller
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   612
            return null;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   613
        return new UnreflectResult(mh, kind, mem, variation);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   614
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   615
    static boolean canBeReached(Member mem, Class<?> cls) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   616
        Class<?> defc = mem.getDeclaringClass();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   617
        String   name = mem.getName();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   618
        int      mods = mem.getModifiers();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   619
        if (mem instanceof Constructor) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   620
            name = "<init>";  // according to 292 spec.
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   621
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   622
        if (defc == cls)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   623
            return true;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   624
        if (name.startsWith("<"))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   625
            return false;  // only my own constructors
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   626
        if (Modifier.isPrivate(mods))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   627
            return false;  // only my own constructors
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   628
        if (defc.getPackage() == cls.getPackage())
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   629
            return true;   // package access or greater OK
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   630
        if (Modifier.isPublic(mods))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   631
            return true;   // publics always OK
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   632
        if (Modifier.isProtected(mods) && defc.isAssignableFrom(cls))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   633
            return true;   // protected OK
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   634
        return false;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   635
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   636
    static boolean consistent(UnreflectResult res, MethodHandleInfo info) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   637
        assert(res.mh != null);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   638
        assertEquals(res.kind, info.getReferenceKind());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   639
        assertEquals(res.mem.getModifiers(), info.getModifiers());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   640
        assertEquals(res.mem.getDeclaringClass(), info.getDeclaringClass());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   641
        String expectName = res.mem.getName();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   642
        if (res.kind == REF_newInvokeSpecial)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   643
            expectName = "<init>";
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   644
        assertEquals(expectName, info.getName());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   645
        MethodType expectType = res.mh.type();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   646
        if ((res.kind & 1) == (REF_getField & 1))
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   647
            expectType = expectType.dropParameterTypes(0, 1);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   648
        if (res.kind == REF_newInvokeSpecial)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   649
            expectType = expectType.changeReturnType(void.class);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   650
        assertEquals(expectType, info.getMethodType());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   651
        assertEquals(res.mh.isVarargsCollector(), isVarArgs(info));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   652
        assertEquals(res.toInfoString(), info.toString());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   653
        assertEquals(res.toInfoString(), MethodHandleInfo.toString(info.getReferenceKind(), info.getDeclaringClass(), info.getName(), info.getMethodType()));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   654
        return true;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   655
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   656
    static boolean isVarArgs(MethodHandleInfo info) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   657
        return info.isVarArgs();
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   658
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   659
    static boolean consistent(Member mem, Member mem2) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   660
        assertEquals(mem, mem2);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   661
        return true;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   662
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   663
    static boolean consistent(MethodHandleInfo info, MethodHandleInfo info2) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   664
        assertEquals(info.getReferenceKind(), info2.getReferenceKind());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   665
        assertEquals(info.getModifiers(), info2.getModifiers());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   666
        assertEquals(info.getDeclaringClass(), info2.getDeclaringClass());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   667
        assertEquals(info.getName(), info2.getName());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   668
        assertEquals(info.getMethodType(), info2.getMethodType());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   669
        assertEquals(isVarArgs(info), isVarArgs(info));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   670
        return true;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   671
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   672
    static boolean consistent(MethodHandle mh, MethodHandle mh2) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   673
        assertEquals(mh.type(), mh2.type());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   674
        assertEquals(mh.isVarargsCollector(), mh2.isVarargsCollector());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   675
        return true;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   676
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   677
    int[] failureModeCounts;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   678
    static final int NO_FAIL=0, FAIL_LOOKUP=1, FAIL_REVEAL=2, FAIL_REFLECT=3, FAIL_MODE_COUNT=4;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   679
    void testWithMember(Member mem,
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   680
                        Lookup lookup,      // initial lookup of member => MH
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   681
                        Lookup revLookup,   // reveal MH => info
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   682
                        Lookup refLookup,   // reflect info => member
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   683
                        int failureMode) throws Throwable {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   684
        boolean expectEx1 = (failureMode == FAIL_LOOKUP);   // testOnMembersNoLookup
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   685
        boolean expectEx2 = (failureMode == FAIL_REVEAL);   // testOnMembersNoReveal
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   686
        boolean expectEx3 = (failureMode == FAIL_REFLECT);  // testOnMembersNoReflect
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   687
        for (int variation = 0; ; variation++) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   688
            UnreflectResult res = unreflectMember(lookup, mem, variation);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   689
            failureModeCounts[failureMode] += 1;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   690
            if (variation == 0)  assert(res != null);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   691
            if (res == null)  break;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   692
            if (VERBOSE && variation == 0)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   693
                System.out.println("from "+mem.getDeclaringClass().getSimpleName());
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   694
            MethodHandle mh = res.mh;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   695
            Throwable   ex1 = res.ex;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   696
            if (VERBOSE)  System.out.println("  "+variation+": "+res+"  << "+(mh != null ? mh : ex1));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   697
            if (expectEx1 && ex1 != null)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   698
                continue;  // this is OK; we expected that lookup to fail
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   699
            if (expectEx1)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   700
                throw new AssertionError("unexpected lookup for negative test");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   701
            if (ex1 != null && !expectEx1) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   702
                if (failureMode != NO_FAIL)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   703
                    throw new AssertionError("unexpected lookup failure for negative test", ex1);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   704
                throw ex1;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   705
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   706
            MethodHandleInfo info;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   707
            try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   708
                info = revLookup.revealDirect(mh);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   709
                if (expectEx2)  throw new AssertionError("unexpected revelation for negative test");
20535
cc85c8626435 8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents: 19804
diff changeset
   710
            } catch (IllegalArgumentException|SecurityException ex2) {
19804
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   711
                if (VERBOSE)  System.out.println("  "+variation+": "+res+" => "+mh.getClass().getName()+" => (EX2)"+ex2);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   712
                if (expectEx2)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   713
                    continue;  // this is OK; we expected the reflect to fail
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   714
                if (failureMode != NO_FAIL)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   715
                    throw new AssertionError("unexpected revelation failure for negative test", ex2);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   716
                throw ex2;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   717
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   718
            assert(consistent(res, info));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   719
            Member mem2;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   720
            try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   721
                mem2 = info.reflectAs(Member.class, refLookup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   722
                if (expectEx3)  throw new AssertionError("unexpected reflection for negative test");
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   723
                assert(!(mem instanceof SignaturePolymorphicMethod));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   724
            } catch (IllegalArgumentException ex3) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   725
                if (VERBOSE)  System.out.println("  "+variation+": "+info+" => (EX3)"+ex3);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   726
                if (expectEx3)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   727
                    continue;  // this is OK; we expected the reflect to fail
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   728
                if (mem instanceof SignaturePolymorphicMethod)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   729
                    continue;  // this is OK; we cannot reflect MH.invokeExact(a,b,c)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   730
                if (failureMode != NO_FAIL)
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   731
                    throw new AssertionError("unexpected reflection failure for negative test", ex3);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   732
                throw ex3;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   733
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   734
            assert(consistent(mem, mem2));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   735
            UnreflectResult res2 = unreflectMember(lookup, mem2, variation);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   736
            MethodHandle mh2 = res2.mh;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   737
            assert(consistent(mh, mh2));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   738
            MethodHandleInfo info2 = lookup.revealDirect(mh2);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   739
            assert(consistent(info, info2));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   740
            assert(consistent(res, info2));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   741
            Member mem3;
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   742
            if (hasSM())
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   743
                mem3 = info2.reflectAs(Member.class, lookup);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   744
            else
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   745
                mem3 = MethodHandles.reflectAs(Member.class, mh2);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   746
            assert(consistent(mem2, mem3));
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   747
            if (hasSM()) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   748
                try {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   749
                    MethodHandles.reflectAs(Member.class, mh2);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   750
                    throw new AssertionError("failed to throw on "+mem3);
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   751
                } catch (SecurityException ex3) {
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   752
                    // OK...
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   753
                }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   754
            }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   755
        }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   756
    }
83170920c07b 8008688: Make MethodHandleInfo public
rfield
parents:
diff changeset
   757
}