1 package runtime.valhalla.nestmates.p2;
   2 
   3 import runtime.valhalla.nestmates.p1.Sup;
   4 
   5 import java.lang.invoke.MethodHandle;
   6 import java.lang.invoke.MethodHandles;
   7 import java.lang.invoke.MethodType;
   8 
   9 public class MethodHandleSubTop extends Sup {
  10 
  11     private final MethodHandles.Lookup METHOD_HANDLE_LOOKUP = MethodHandles.lookup();
  12     private final MethodType METHOD_TYPE = MethodType.methodType(int.class);
  13 
  14     // verify access check to a "super" method, method can be used in positive and negative test case
  15     public MethodHandle getSuperMethodMH(String methodName) throws NoSuchMethodException, IllegalAccessException {
  16         return METHOD_HANDLE_LOOKUP.findVirtual(this.getClass(), methodName, METHOD_TYPE);
  17     }
  18 
  19     // verify access check to a "super" field, method can be used in positive and negative test case
  20     public MethodHandle getSuperFieldMH(String fieldName) throws NoSuchFieldException, IllegalAccessException {
  21         return METHOD_HANDLE_LOOKUP.findGetter(this.getClass(), fieldName, int.class);
  22     }
  23 
  24     public class Inner {
  25 
  26         public Inner() {
  27             getField(); // to force javac to create a bridge
  28             int x = field; // to force javac to create a bridge
  29         }
  30 
  31         // verify presence of an access bridge for a "super" method
  32         public MethodHandle getSuperProtectedMethodMH() throws Throwable {
  33             MethodType mt = MethodType.methodType(int.class, this.getClass().getEnclosingClass());
  34             MethodHandle mh = METHOD_HANDLE_LOOKUP.findStatic(this.getClass().getEnclosingClass(), "access$000", mt);
  35             return mh;
  36         }
  37 
  38         // verify presence of an access bridge for a "super" field
  39         public MethodHandle getSuperProtectedFieldMH() throws Throwable {
  40             MethodType mt = MethodType.methodType(int.class, this.getClass().getEnclosingClass());
  41             MethodHandle mh = METHOD_HANDLE_LOOKUP.findStatic(this.getClass().getEnclosingClass(), "access$100", mt);
  42             return mh;
  43         }
  44 
  45         // verify access check to a "super" method without an access bridge
  46         public MethodHandle getSuperMethodMH(String methodName) throws NoSuchMethodException, IllegalAccessException {
  47             return METHOD_HANDLE_LOOKUP.findVirtual(this.getClass(), methodName, METHOD_TYPE);
  48         }
  49 
  50         // verify access check to a "super" field without an access bridge
  51         public MethodHandle getSuperFieldMH(String fieldName) throws NoSuchFieldException, IllegalAccessException {
  52             return METHOD_HANDLE_LOOKUP.findGetter(this.getClass(), fieldName, int.class);
  53         }
  54 
  55         public class InnerInner {
  56 
  57             public InnerInner() {
  58                 getField(); // to force javac to create a bridge
  59                 int x = field; // to force javac to create a bridge
  60             }
  61 
  62             // verify presence of an access bridge for a "super" method
  63             public MethodHandle getSuperProtectedMethodMH() throws Throwable {
  64                 MethodType mt = MethodType.methodType(int.class, MethodHandleSubTop.class);
  65                 MethodHandle mh = METHOD_HANDLE_LOOKUP.findStatic(MethodHandleSubTop.class, "access$400", mt);
  66                 return mh;
  67             }
  68 
  69             // verify presence of an access bridge for a "super" field
  70             public MethodHandle getSuperProtectedFieldMH() throws Throwable {
  71                 MethodType mt = MethodType.methodType(int.class, MethodHandleSubTop.class);
  72                 MethodHandle mh = METHOD_HANDLE_LOOKUP.findStatic(MethodHandleSubTop.class, "access$500", mt);
  73                 return mh;
  74             }
  75 
  76             // verify access check to a "super" method without an access bridge
  77             public MethodHandle getSuperMethodMH(String methodName) throws NoSuchMethodException, IllegalAccessException {
  78                 return METHOD_HANDLE_LOOKUP.findVirtual(this.getClass(), methodName, METHOD_TYPE);
  79             }
  80 
  81             // verify access check to a "super" field without an access bridge
  82             public MethodHandle getSuperFieldMH(String fieldName) throws NoSuchFieldException, IllegalAccessException {
  83                 return METHOD_HANDLE_LOOKUP.findGetter(this.getClass(), fieldName, int.class);
  84             }
  85         }
  86     }
  87 
  88 }