1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package runtime.valhalla.nestmates.p2;
  25 
  26 import runtime.valhalla.nestmates.p1.Sup;
  27 
  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.MethodType;
  31 
  32 public class MethodHandleSubTop extends Sup {
  33 
  34     final MethodHandles.Lookup METHOD_HANDLE_LOOKUP = MethodHandles.lookup();
  35     final MethodType METHOD_TYPE = MethodType.methodType(int.class);
  36 
  37     // verify access check to a "super" method, method can be used in positive and negative test case
  38     public MethodHandle getSuperMethodMH(String methodName) throws NoSuchMethodException, IllegalAccessException {
  39         return METHOD_HANDLE_LOOKUP.findVirtual(this.getClass(), methodName, METHOD_TYPE);
  40     }
  41 
  42     // verify access check to a "super" field, method can be used in positive and negative test case
  43     public MethodHandle getSuperFieldMH(String fieldName) throws NoSuchFieldException, IllegalAccessException {
  44         return METHOD_HANDLE_LOOKUP.findGetter(this.getClass(), fieldName, int.class);
  45     }
  46 
  47     public class Inner {
  48 
  49         public Inner() {
  50             getField(); // to force javac to create a bridge
  51             int x = field; // to force javac to create a bridge
  52         }
  53 
  54         // verify presence of an access bridge for a "super" method
  55         public MethodHandle getSuperProtectedMethodMH() throws Throwable {
  56             MethodType mt = MethodType.methodType(int.class, this.getClass().getEnclosingClass());
  57             MethodHandle mh = METHOD_HANDLE_LOOKUP.findStatic(this.getClass().getEnclosingClass(), "access$000", mt);
  58             return mh;
  59         }
  60 
  61         // verify presence of an access bridge for a "super" field
  62         public MethodHandle getSuperProtectedFieldMH() throws Throwable {
  63             MethodType mt = MethodType.methodType(int.class, this.getClass().getEnclosingClass());
  64             MethodHandle mh = METHOD_HANDLE_LOOKUP.findStatic(this.getClass().getEnclosingClass(), "access$100", mt);
  65             return mh;
  66         }
  67 
  68         // verify access check to a "super" method without an access bridge
  69         public MethodHandle getSuperMethodMH(String methodName) throws NoSuchMethodException, IllegalAccessException {
  70             return METHOD_HANDLE_LOOKUP.findVirtual(this.getClass(), methodName, METHOD_TYPE);
  71         }
  72 
  73         // verify access check to a "super" field without an access bridge
  74         public MethodHandle getSuperFieldMH(String fieldName) throws NoSuchFieldException, IllegalAccessException {
  75             return METHOD_HANDLE_LOOKUP.findGetter(this.getClass(), fieldName, int.class);
  76         }
  77 
  78         public class InnerInner {
  79 
  80             public InnerInner() {
  81                 getField(); // to force javac to create a bridge
  82                 int x = field; // to force javac to create a bridge
  83             }
  84 
  85             // verify presence of an access bridge for a "super" method
  86             public MethodHandle getSuperProtectedMethodMH() throws Throwable {
  87                 MethodType mt = MethodType.methodType(int.class, MethodHandleSubTop.class);
  88                 MethodHandle mh = METHOD_HANDLE_LOOKUP.findStatic(MethodHandleSubTop.class, "access$400", mt);
  89                 return mh;
  90             }
  91 
  92             // verify presence of an access bridge for a "super" field
  93             public MethodHandle getSuperProtectedFieldMH() throws Throwable {
  94                 MethodType mt = MethodType.methodType(int.class, MethodHandleSubTop.class);
  95                 MethodHandle mh = METHOD_HANDLE_LOOKUP.findStatic(MethodHandleSubTop.class, "access$500", mt);
  96                 return mh;
  97             }
  98 
  99             // verify access check to a "super" method without an access bridge
 100             public MethodHandle getSuperMethodMH(String methodName) throws NoSuchMethodException, IllegalAccessException {
 101                 return METHOD_HANDLE_LOOKUP.findVirtual(this.getClass(), methodName, METHOD_TYPE);
 102             }
 103 
 104             // verify access check to a "super" field without an access bridge
 105             public MethodHandle getSuperFieldMH(String fieldName) throws NoSuchFieldException, IllegalAccessException {
 106                 return METHOD_HANDLE_LOOKUP.findGetter(this.getClass(), fieldName, int.class);
 107             }
 108         }
 109     }
 110 
 111 }