1 /*
   2  * Copyright (c) 2018, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 import java.lang.invoke.MethodHandles;
  27 import java.lang.invoke.MethodType;
  28 import java.lang.constant.*;
  29 import java.lang.Enum.EnumDesc;
  30 import java.util.function.Supplier;
  31 
  32 import org.testng.annotations.Test;
  33 
  34 import static java.lang.invoke.Intrinsics.ldc;
  35 import static java.lang.constant.DirectMethodHandleDesc.Kind.*;
  36 import static org.testng.Assert.assertEquals;
  37 import static org.testng.Assert.assertNull;
  38 import static org.testng.Assert.fail;
  39 
  40 /**
  41  * @test
  42  * @compile IntrinsifiedRefTest.java
  43  * @run testng IntrinsifiedRefTest
  44  * @summary Integration test for intrinsification of XxxRef
  45  */
  46 @Test
  47 public class IntrinsifiedRefTest {
  48     public static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
  49 
  50     private static final ClassDesc CR_THIS = ClassDesc.of("IntrinsifiedRefTest");
  51     private static final ClassDesc CR_TESTCLASS = CR_THIS.inner("TestClass");
  52     private static final ClassDesc CR_TESTINTF = CR_THIS.inner("TestInterface");
  53     private static final ClassDesc CR_TESTSUPERCLASS = CR_THIS.inner("TestSuperclass");
  54     private static final ClassDesc CR_TESTENUM = CR_THIS.inner("TestEnum");
  55     private static final String NONEXISTENT_CLASS = "foo.Bar";
  56     private static final String INACCESSIBLE_CLASS = "java.lang.invoke.DirectMethodHandle";
  57 
  58     private static final MethodHandleDesc MHR_TESTCLASS_CTOR = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.CONSTRUCTOR, CR_TESTCLASS, "<ignored!>", MethodTypeDesc.ofDescriptor("()V"));
  59     private static final MethodHandleDesc MHR_TESTCLASS_SM = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_TESTCLASS, "sm", "(I)I");
  60     private static final MethodHandleDesc MHR_TESTINTF_SM = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_TESTINTF, "sm", "(I)I");
  61     private static final MethodHandleDesc MHR_TESTCLASS_M = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.VIRTUAL, CR_TESTCLASS, "m", MethodTypeDesc.ofDescriptor("(I)I"));
  62     private static final MethodHandleDesc MHR_TESTINTF_M = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, CR_TESTINTF, "m", MethodTypeDesc.ofDescriptor("(I)I"));
  63     private static final MethodHandleDesc MHR_TESTCLASS_PM_SPECIAL = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.SPECIAL, CR_TESTCLASS, "pm", MethodTypeDesc.ofDescriptor("(I)I"));
  64     private static final MethodHandleDesc MHR_TESTINTF_PM_SPECIAL = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.SPECIAL, CR_TESTINTF, "pm", MethodTypeDesc.ofDescriptor("(I)I"));
  65     private static final MethodHandleDesc MHR_TESTCLASS_PSM = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_TESTCLASS, "psm", MethodTypeDesc.ofDescriptor("(I)I"));
  66     private static final MethodHandleDesc MHR_TESTINTF_PSM = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_TESTINTF, "psm", MethodTypeDesc.ofDescriptor("(I)I"));
  67     private static final MethodHandleDesc MHR_TESTSUPER_M_SPECIAL = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.SPECIAL, CR_TESTSUPERCLASS, "m", "(I)I");
  68     private static final MethodHandleDesc MHR_TESTINTF_M_SPECIAL = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.SPECIAL, CR_TESTINTF, "m", "(I)I");
  69     private static final MethodHandleDesc MHR_TESTCLASS_SF_SETTER = MethodHandleDesc.ofField(STATIC_SETTER, CR_TESTCLASS, "sf", ConstantDescs.CR_int);
  70     private static final MethodHandleDesc MHR_TESTCLASS_SF_GETTER = MethodHandleDesc.ofField(STATIC_GETTER, CR_TESTCLASS, "sf", ConstantDescs.CR_int);
  71     private static final MethodHandleDesc MHR_TESTINTF_SF_GETTER = MethodHandleDesc.ofField(STATIC_GETTER, CR_TESTINTF, "sf", ConstantDescs.CR_int);
  72     private static final MethodHandleDesc MHR_TESTCLASS_F_SETTER = MethodHandleDesc.ofField(SETTER, CR_TESTCLASS, "f", ConstantDescs.CR_int);
  73     private static final MethodHandleDesc MHR_TESTCLASS_F_GETTER = MethodHandleDesc.ofField(GETTER, CR_TESTCLASS, "f", ConstantDescs.CR_int);
  74 
  75 
  76 
  77     private static <T extends Constable> void assertIntrinsic(ConstantDesc<T> ref, T intrinsified, T target) throws ReflectiveOperationException {
  78         assertEquals(target, intrinsified);
  79         assertEquals(ref.resolveConstantDesc(LOOKUP), intrinsified);
  80         assertEquals(intrinsified.describeConstable().orElseThrow(), ref);
  81     }
  82 
  83     private static<T extends Constable> void assertIntrinsicFail(ConstantDesc<T> ref, Supplier<T> supplier, Class<? extends Throwable> exception) {
  84         try {
  85             T t = supplier.get();
  86             fail("Expected failure resolving " + ref);
  87         } catch (Throwable e) {
  88             if (exception.isAssignableFrom(e.getClass()))
  89                 return;
  90             else if (e instanceof BootstrapMethodError) {
  91                 Throwable cause = e.getCause();
  92                 if (cause != null && exception.isAssignableFrom(cause.getClass()))
  93                     return;
  94             }
  95             fail(String.format("Expected %s, found %s for %s", exception, e.getClass(), ref));
  96         }
  97     }
  98 
  99     public void testLdcClass() throws ReflectiveOperationException {
 100         ClassDesc cr1 = ClassDesc.ofDescriptor("Ljava/lang/String;");
 101         ClassDesc cr2 = ClassDesc.of("java.lang.String");
 102         ClassDesc cr3 = ClassDesc.of("java.lang", "String");
 103 
 104         assertIntrinsic(cr1, ldc(cr1), String.class);
 105         assertIntrinsic(cr2, ldc(cr2), String.class);
 106         assertIntrinsic(cr3, ldc(cr3), String.class);
 107 
 108         ClassDesc cr4 = ClassDesc.ofDescriptor("[Ljava/lang/String;");
 109         ClassDesc cr5 = cr2.arrayType();
 110         assertIntrinsic(cr4, ldc(cr4), String[].class);
 111         assertIntrinsic(cr5, ldc(cr5), String[].class);
 112 
 113         ClassDesc cr6 = ClassDesc.ofDescriptor("I");
 114         assertIntrinsic(cr6, ldc(cr6), int.class);
 115         assertIntrinsic(ConstantDescs.CR_int, ldc(ConstantDescs.CR_int), int.class);
 116 
 117         ClassDesc cr7 = ClassDesc.ofDescriptor("[I");
 118         ClassDesc cr8 = ConstantDescs.CR_int.arrayType();
 119         assertIntrinsic(cr7, ldc(cr7), int[].class);
 120         assertIntrinsic(cr8, ldc(cr8), int[].class);
 121     }
 122 
 123     public void negLdcClass() {
 124         ClassDesc cr = ClassDesc.of(NONEXISTENT_CLASS);
 125         assertIntrinsicFail(cr, () -> ldc(cr), NoClassDefFoundError.class);
 126 
 127         ClassDesc cr2 = ClassDesc.of(INACCESSIBLE_CLASS);
 128         assertIntrinsicFail(cr2, () -> ldc(cr2), IllegalAccessError.class);
 129     }
 130 
 131     public void testLdcMethodType() throws ReflectiveOperationException {
 132         MethodTypeDesc mtr1 = MethodTypeDesc.ofDescriptor("()V");
 133         MethodTypeDesc mtr2 = MethodTypeDesc.of(ConstantDescs.CR_void);
 134         assertIntrinsic(mtr1, ldc(mtr1), MethodType.methodType(void.class));
 135         assertIntrinsic(mtr2, ldc(mtr2), MethodType.methodType(void.class));
 136 
 137         MethodTypeDesc mtr3 = MethodTypeDesc.ofDescriptor("(I)I");
 138         MethodTypeDesc mtr4 = MethodTypeDesc.of(ConstantDescs.CR_int, ConstantDescs.CR_int);
 139         assertIntrinsic(mtr3, ldc(mtr3), MethodType.methodType(int.class, int.class));
 140         assertIntrinsic(mtr4, ldc(mtr4), MethodType.methodType(int.class, int.class));
 141 
 142         MethodTypeDesc mtr5 = MethodTypeDesc.ofDescriptor("(Ljava/lang/String;)Ljava/lang/String;");
 143         MethodTypeDesc mtr6 = MethodTypeDesc.of(ConstantDescs.CR_String, ConstantDescs.CR_String);
 144         assertIntrinsic(mtr5, ldc(mtr5), MethodType.methodType(String.class, String.class));
 145         assertIntrinsic(mtr6, ldc(mtr6), MethodType.methodType(String.class, String.class));
 146 
 147         MethodTypeDesc mtr7 = MethodTypeDesc.ofDescriptor("([I)[Ljava/lang/String;");
 148         assertIntrinsic(mtr7, ldc(mtr7), MethodType.methodType(String[].class, int[].class));
 149     }
 150 
 151     public void negLdcMethodType() {
 152         MethodTypeDesc mtr1 = MethodTypeDesc.of(ClassDesc.of(NONEXISTENT_CLASS));
 153         assertIntrinsicFail(mtr1, () -> ldc(mtr1), NoClassDefFoundError.class);
 154 
 155         MethodTypeDesc mtr2 = MethodTypeDesc.of(ClassDesc.of(INACCESSIBLE_CLASS));
 156         assertIntrinsicFail(mtr2, () -> ldc(mtr2), IllegalAccessError.class);
 157     }
 158 
 159     public void testLdcEnum() throws ReflectiveOperationException {
 160         EnumDesc<TestEnum> enr1 = EnumDesc.of(CR_TESTENUM, "A");
 161         assertIntrinsic(enr1, ldc(enr1), TestEnum.A);
 162 
 163         EnumDesc<TestEnum> enr2 = EnumDesc.of(CR_TESTENUM, "B");
 164         assertIntrinsic(enr2, ldc(enr2), TestEnum.B);
 165     }
 166 
 167     public void negLdcEnum() {
 168         EnumDesc<TestEnum> enr1 = EnumDesc.of(CR_TESTENUM, "C");
 169         assertIntrinsicFail(enr1, () -> ldc(enr1), IllegalArgumentException.class);
 170 
 171         EnumDesc<TestEnum> enr2 = EnumDesc.of(ClassDesc.of(NONEXISTENT_CLASS), "A");
 172         assertIntrinsicFail(enr2, () -> ldc(enr2), NoClassDefFoundError.class);
 173 
 174         EnumDesc<TestEnum> enr3 = EnumDesc.of(CR_THIS, "A");
 175         assertIntrinsicFail(enr3, () -> ldc(enr3), IllegalArgumentException.class);
 176 
 177         EnumDesc<TestEnum> enr4 = EnumDesc.of(ClassDesc.of(INACCESSIBLE_CLASS), "A");
 178         assertIntrinsicFail(enr4, () -> ldc(enr4), IllegalAccessError.class);
 179     }
 180 
 181     public void testLdcSelfConstants() throws ReflectiveOperationException {
 182         assertIntrinsic("Foo", ldc("Foo"), "Foo");
 183         assertIntrinsic(1, ldc(1), 1);
 184         assertIntrinsic(1L, ldc(1L), 1L);
 185         assertIntrinsic(2.0f, ldc(2.0f), 2.0f);
 186         assertIntrinsic(3.0d, ldc(3.0d), 3.0d);
 187     }
 188 
 189     public void testLdcMethodHandleFromInner() throws Throwable {
 190         TestClass.ldcMethodHandleFromInner();
 191         TestClass.negLdcMethodHandleFromInner();
 192         TestInterface.testLdcMethodHandleFromIntf(new TestInterface(){});
 193     }
 194 
 195     public void testLdcMethodHandle() throws Throwable {
 196         TestClass instance = (TestClass) ldc(MHR_TESTCLASS_CTOR).invokeExact();
 197 
 198         assertEquals(5, (int) ldc(MHR_TESTCLASS_SM).invokeExact(5));
 199         assertEquals(0, (int) ldc(MHR_TESTINTF_SM).invokeExact(5));
 200 
 201         assertEquals(5, (int) ldc(MHR_TESTCLASS_M).invokeExact(instance, 5));
 202         assertEquals(5, (int) ldc(MHR_TESTINTF_M).invoke(instance, 5));
 203 
 204         ldc(MHR_TESTCLASS_SF_SETTER).invokeExact(8);
 205         assertEquals(TestClass.sf, 8);
 206         assertEquals(8, (int) ldc(MHR_TESTCLASS_SF_GETTER).invokeExact());
 207 
 208         assertEquals(3, (int) ldc(MHR_TESTINTF_SF_GETTER).invokeExact());
 209 
 210         ldc(MHR_TESTCLASS_F_SETTER).invokeExact(instance, 9); assertEquals(instance.f, 9);
 211         assertEquals(9, (int) ldc(MHR_TESTCLASS_F_GETTER).invokeExact(instance));
 212     }
 213 
 214     public void testNegLdcMethodHandle() {
 215         // Accessible classes, inaccessible methods
 216         assertIntrinsicFail(MHR_TESTCLASS_PM_SPECIAL, () -> ldc(MHR_TESTCLASS_PM_SPECIAL), IllegalAccessError.class);
 217         // these are passing now that we have nestmates
 218 //        assertIntrinsicFail(MHR_TESTINTF_PM_SPECIAL, () -> ldc(MHR_TESTINTF_PM_SPECIAL), IllegalAccessError.class);
 219 //        assertIntrinsicFail(MHR_TESTCLASS_PSM, () -> ldc(MHR_TESTCLASS_PSM), IllegalAccessError.class);
 220 //        assertIntrinsicFail(MHR_TESTINTF_PSM, () -> ldc(MHR_TESTINTF_PSM), IllegalAccessError.class);
 221 
 222         // Accessible class and method, but illegal super access
 223         assertIntrinsicFail(MHR_TESTSUPER_M_SPECIAL, () -> ldc(MHR_TESTSUPER_M_SPECIAL), IllegalAccessError.class);
 224         assertIntrinsicFail(MHR_TESTINTF_M_SPECIAL, () -> ldc(MHR_TESTINTF_M_SPECIAL), IncompatibleClassChangeError.class);
 225 
 226         // Method kind mismatches -- intf, virtual, static
 227         MethodHandleDesc intfMethodAsVirtual = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.VIRTUAL, CR_TESTINTF, "m", MethodTypeDesc.ofDescriptor("(I)I"));
 228         MethodHandleDesc intfMethodAsStatic = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_TESTINTF, "m", MethodTypeDesc.ofDescriptor("(I)I"));
 229         MethodHandleDesc virtualMethodAsIntf = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, CR_TESTCLASS, "m", MethodTypeDesc.ofDescriptor("(I)I"));
 230         MethodHandleDesc virtualMethodAsStatic = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_TESTCLASS, "m", MethodTypeDesc.ofDescriptor("(I)I"));
 231         MethodHandleDesc staticMethodAsVirtual = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.VIRTUAL, CR_TESTCLASS, "sm", MethodTypeDesc.ofDescriptor("(I)I"));
 232         MethodHandleDesc staticMethodAsIntf = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, CR_TESTINTF, "sm", MethodTypeDesc.ofDescriptor("(I)I"));
 233 
 234         // the ones below fail with a verifier error
 235         //assertIntrinsicFail(intfMethodAsVirtual, () -> ldc(intfMethodAsVirtual), IncompatibleClassChangeError.class);
 236         //assertIntrinsicFail(intfMethodAsStatic, () -> ldc(intfMethodAsStatic), IncompatibleClassChangeError.class);
 237         //assertIntrinsicFail(virtualMethodAsIntf, () -> ldc(virtualMethodAsIntf), IncompatibleClassChangeError.class);
 238 
 239         assertIntrinsicFail(virtualMethodAsStatic, () -> ldc(virtualMethodAsStatic), IncompatibleClassChangeError.class);
 240         assertIntrinsicFail(staticMethodAsVirtual, () -> ldc(staticMethodAsVirtual), IncompatibleClassChangeError.class);
 241         assertIntrinsicFail(staticMethodAsIntf, () -> ldc(staticMethodAsIntf), IncompatibleClassChangeError.class);
 242 
 243         // Field kind mismatch -- instance/static
 244         MethodHandleDesc staticFieldAsInstance = MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.GETTER, CR_TESTCLASS, "sf", ConstantDescs.CR_int);
 245         MethodHandleDesc instanceFieldAsStatic = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC_GETTER, CR_TESTCLASS, "f", ConstantDescs.CR_int);
 246 
 247         assertIntrinsicFail(staticFieldAsInstance, () -> ldc(staticFieldAsInstance), IncompatibleClassChangeError.class);
 248         assertIntrinsicFail(instanceFieldAsStatic, () -> ldc(instanceFieldAsStatic), IncompatibleClassChangeError.class);
 249 
 250         // Setter for final field
 251         MethodHandleDesc finalStaticSetter = MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.STATIC_SETTER, CR_TESTCLASS, "sff", ConstantDescs.CR_int);
 252         MethodHandleDesc finalSetter = MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.SETTER, CR_TESTCLASS, "ff", ConstantDescs.CR_int);
 253 
 254         assertIntrinsicFail(finalStaticSetter, () -> ldc(finalStaticSetter), IllegalAccessError.class);
 255         assertIntrinsicFail(finalSetter, () -> ldc(finalSetter), IllegalAccessError.class);
 256 
 257         // Nonexistent owner
 258         MethodHandleDesc r1 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, ClassDesc.of(NONEXISTENT_CLASS), "m", "()V");
 259         assertIntrinsicFail(r1, () -> ldc(r1), NoClassDefFoundError.class);
 260 
 261         // Inaccessible owner
 262         MethodHandleDesc r2 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, ClassDesc.of(INACCESSIBLE_CLASS), "m", "()V");
 263         assertIntrinsicFail(r2, () -> ldc(r2), IllegalAccessError.class);
 264 
 265         // Nonexistent method, ctor, field
 266         MethodHandleDesc r3 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_TESTCLASS, "nonexistent", "()V");
 267         MethodHandleDesc r4 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.VIRTUAL, CR_TESTCLASS, "nonexistent", "()V");
 268         MethodHandleDesc r5 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.CONSTRUCTOR, CR_TESTCLASS, "<ignored>", "(I)V");
 269         MethodHandleDesc r6 = MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.GETTER, CR_TESTCLASS, "nonexistent", ConstantDescs.CR_int);
 270         MethodHandleDesc r7 = MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.SETTER, CR_TESTCLASS, "nonexistent", ConstantDescs.CR_int);
 271         MethodHandleDesc r8 = MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.STATIC_GETTER, CR_TESTCLASS, "nonexistent", ConstantDescs.CR_int);
 272         MethodHandleDesc r9 = MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.STATIC_SETTER, CR_TESTCLASS, "nonexistent", ConstantDescs.CR_int);
 273 
 274         assertIntrinsicFail(r3, () -> ldc(r3), NoSuchMethodError.class);
 275         assertIntrinsicFail(r4, () -> ldc(r4), NoSuchMethodError.class);
 276         assertIntrinsicFail(r5, () -> ldc(r5), NoSuchMethodError.class);
 277         assertIntrinsicFail(r6, () -> ldc(r6), NoSuchFieldError.class);
 278         assertIntrinsicFail(r7, () -> ldc(r7), NoSuchFieldError.class);
 279         assertIntrinsicFail(r8, () -> ldc(r8), NoSuchFieldError.class);
 280         assertIntrinsicFail(r9, () -> ldc(r9), NoSuchFieldError.class);
 281     }
 282 
 283     public void testLdcDynamicConstants() throws ReflectiveOperationException {
 284         assertNull(ldc(ConstantDescs.NULL));
 285         assertIntrinsic(ConstantDescs.CR_int, ldc(ConstantDescs.CR_int), int.class);
 286         // @@@ VarHandle
 287         // @@@ invoke (including multiple deep)
 288     }
 289 
 290     public void negLdcDynamicConstants() {
 291         // @@@ negative tests for nonexistent/inaccessible bootstrap
 292         // @@@ negative tests for bootstrap parameter mismatch
 293     }
 294 
 295     private enum TestEnum {
 296         A, B;
 297     }
 298 
 299     private interface TestInterface {
 300         public static final int sf = 3;
 301 
 302         static int sm(int x) { return 0; }
 303         default int m(int x) { return 0; }
 304         private int pm(int x) { return 1; }
 305         private static int psm(int x) { return 2; }
 306 
 307         static void testLdcMethodHandleFromIntf(TestInterface testInterface) throws Throwable {
 308             assertEquals(1, ldc(MHR_TESTINTF_PM_SPECIAL).invoke(testInterface, 1));
 309             assertEquals(2, ldc(MHR_TESTINTF_PSM).invoke(1));
 310         }
 311     }
 312 
 313     private static class TestSuperclass {
 314         public int m(int x) { return -1; }
 315     }
 316 
 317     private static class TestClass extends TestSuperclass implements TestInterface {
 318 
 319         static final int sff = 7;
 320         static final int ff = 8;
 321 
 322         static int sf;
 323         int f;
 324 
 325         public TestClass()  {}
 326 
 327         public static int sm(int x) { return x; }
 328         public int m(int x) { return x; }
 329         private static int psm(int x) { return x; }
 330         private int pm(int x) { return x; }
 331 
 332         private static void negLdcMethodHandleFromInner() {
 333             // When we have nestmates, these will probably start succeeding,
 334             // at which point we will need to find new negative tests for super-access.
 335 //            assertIntrinsicFail(MHR_TESTINTF_PM_SPECIAL, () -> ldc(MHR_TESTINTF_PM_SPECIAL), IllegalAccessError.class);
 336 //            assertIntrinsicFail(MHR_TESTINTF_PSM, () -> ldc(MHR_TESTINTF_PSM), IllegalAccessError.class);
 337         }
 338 
 339         private static void ldcMethodHandleFromInner() throws Throwable {
 340             TestClass instance = (TestClass) ldc(MHR_TESTCLASS_CTOR).invokeExact();
 341 
 342             assertEquals(-1, (int) ldc(MHR_TESTSUPER_M_SPECIAL).invokeExact(instance, 5));
 343             assertEquals(0, (int) ldc(MHR_TESTINTF_M_SPECIAL).invokeExact(instance, 5));
 344 
 345             assertEquals(5, (int) ldc(MHR_TESTCLASS_PM_SPECIAL).invokeExact(instance, 5));
 346 
 347             assertEquals(5, (int) ldc(MHR_TESTCLASS_PSM).invokeExact(5));
 348         }
 349 
 350     }
 351 
 352     private static int privateStaticMethod(int i) {
 353         return i;
 354     }
 355 
 356     private int privateMethod(int i) {
 357         return i;
 358     }
 359 }