647 testGetter(false, lookup,
648 new Object[]{ (isStaticN != 0), System.class, "bogus", char.class },
649 null, testMode);
650 }
651 }
652
653 public void testGetter(boolean positive, MethodHandles.Lookup lookup,
654 Object fieldRef, Object value, int testMode) throws Throwable {
655 testAccessor(positive, lookup, fieldRef, value, testMode);
656 }
657
658 public void testAccessor(boolean positive0, MethodHandles.Lookup lookup,
659 Object fieldRef, Object value, int testMode0) throws Throwable {
660 if (verbosity >= 4)
661 System.out.println("testAccessor"+Arrays.deepToString(new Object[]{positive0, lookup, fieldRef, value, testMode0}));
662 boolean isGetter = ((testMode0 & TEST_SETTER) == 0);
663 boolean doBound = ((testMode0 & TEST_BOUND) != 0);
664 boolean testNPE = ((testMode0 & TEST_NPE) != 0);
665 int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE);
666 boolean positive = positive0 && !testNPE;
667 boolean isStatic;
668 Class<?> fclass;
669 String fname;
670 Class<?> ftype;
671 Field f = (fieldRef instanceof Field ? (Field)fieldRef : null);
672 if (f != null) {
673 isStatic = Modifier.isStatic(f.getModifiers());
674 fclass = f.getDeclaringClass();
675 fname = f.getName();
676 ftype = f.getType();
677 } else {
678 Object[] scnt = (Object[]) fieldRef;
679 isStatic = (Boolean) scnt[0];
680 fclass = (Class<?>) scnt[1];
681 fname = (String) scnt[2];
682 ftype = (Class<?>) scnt[3];
683 try {
684 f = fclass.getDeclaredField(fname);
685 } catch (ReflectiveOperationException ex) {
686 f = null;
687 }
688 }
689 if (!testModeMatches(testMode, isStatic)) return;
690 if (f == null && testMode == TEST_UNREFLECT) return;
691 if (testNPE && isStatic) return;
692 countTest(positive);
693 MethodType expType;
694 if (isGetter)
695 expType = MethodType.methodType(ftype, HasFields.class);
696 else
697 expType = MethodType.methodType(void.class, HasFields.class, ftype);
698 if (isStatic) expType = expType.dropParameterTypes(0, 1);
699 Exception noAccess = null;
703 case TEST_UNREFLECT: mh = lookup.unreflectGetter(f); break;
704 case TEST_FIND_FIELD: mh = lookup.findGetter(fclass, fname, ftype); break;
705 case TEST_FIND_STATIC: mh = lookup.findStaticGetter(fclass, fname, ftype); break;
706 case TEST_SETTER|
707 TEST_UNREFLECT: mh = lookup.unreflectSetter(f); break;
708 case TEST_SETTER|
709 TEST_FIND_FIELD: mh = lookup.findSetter(fclass, fname, ftype); break;
710 case TEST_SETTER|
711 TEST_FIND_STATIC: mh = lookup.findStaticSetter(fclass, fname, ftype); break;
712 default:
713 throw new InternalError("testMode="+testMode);
714 }
715 } catch (ReflectiveOperationException ex) {
716 mh = null;
717 noAccess = ex;
718 assertExceptionClass(
719 (fname.contains("bogus"))
720 ? NoSuchFieldException.class
721 : IllegalAccessException.class,
722 noAccess);
723 if (verbosity >= 5) ex.printStackTrace(System.out);
724 }
725 if (verbosity >= 3)
726 System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
727 +" => "+mh
728 +(noAccess == null ? "" : " !! "+noAccess));
729 if (positive && !testNPE && noAccess != null) throw new RuntimeException(noAccess);
730 assertEquals(positive0 ? "positive test" : "negative test erroneously passed", positive0, mh != null);
731 if (!positive && !testNPE) return; // negative access test failed as expected
732 assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount());
733
734
735 assertSame(mh.type(), expType);
736 //assertNameStringContains(mh, fname); // This does not hold anymore with LFs
737 HasFields fields = new HasFields();
738 HasFields fieldsForMH = fields;
739 if (testNPE) fieldsForMH = null; // perturb MH argument to elicit expected error
740 if (doBound)
741 mh = mh.bindTo(fieldsForMH);
742 Object sawValue;
743 Class<?> vtype = ftype;
744 if (ftype != int.class) vtype = Object.class;
745 if (isGetter) {
746 mh = mh.asType(mh.type().generic()
747 .changeReturnType(vtype));
748 } else {
749 int last = mh.type().parameterCount() - 1;
750 mh = mh.asType(mh.type().generic()
751 .changeReturnType(void.class)
752 .changeParameterType(last, vtype));
753 }
754 if (f != null && f.getDeclaringClass() == HasFields.class) {
761 sawValue = null; // make DA rules happy under try/catch
762 try {
763 if (isStatic || doBound) {
764 if (ftype == int.class)
765 sawValue = (int) mh.invokeExact(); // do these exactly
766 else
767 sawValue = mh.invokeExact();
768 } else {
769 if (ftype == int.class)
770 sawValue = (int) mh.invokeExact((Object) fieldsForMH);
771 else
772 sawValue = mh.invokeExact((Object) fieldsForMH);
773 }
774 } catch (RuntimeException ex) {
775 if (ex instanceof NullPointerException && testNPE) {
776 caughtEx = ex;
777 break;
778 }
779 }
780 assertEquals(sawValue, expValue);
781 if (f != null && f.getDeclaringClass() == HasFields.class
782 && !Modifier.isFinal(f.getModifiers())) {
783 Object random = randomArg(ftype);
784 f.set(fields, random);
785 expValue = random;
786 } else {
787 break;
788 }
789 }
790 } else {
791 for (int i = 0; i <= 1; i++) {
792 Object putValue = randomArg(ftype);
793 try {
794 if (isStatic || doBound) {
795 if (ftype == int.class)
796 mh.invokeExact((int)putValue); // do these exactly
797 else
798 mh.invokeExact(putValue);
799 } else {
800 if (ftype == int.class)
801 mh.invokeExact((Object) fieldsForMH, (int)putValue);
802 else
803 mh.invokeExact((Object) fieldsForMH, putValue);
804 }
805 } catch (RuntimeException ex) {
806 if (ex instanceof NullPointerException && testNPE) {
807 caughtEx = ex;
808 break;
809 }
810 }
811 if (f != null && f.getDeclaringClass() == HasFields.class) {
812 assertEquals(f.get(fields), putValue);
813 }
814 }
815 }
816 if (f != null && f.getDeclaringClass() == HasFields.class) {
817 f.set(fields, value); // put it back
818 }
819 if (testNPE) {
820 if (caughtEx == null || !(caughtEx instanceof NullPointerException))
821 throw new RuntimeException("failed to catch NPE exception"+(caughtEx == null ? " (caughtEx=null)" : ""), caughtEx);
822 caughtEx = null; // nullify expected exception
823 }
824 if (caughtEx != null) {
825 throw new RuntimeException("unexpected exception", caughtEx);
826 }
827 }
828
829 @Test
830 public void testUnreflectSetter() throws Throwable {
831 CodeCacheOverflowProcessor.runMHTest(this::testUnreflectSetter0);
832 }
833
834 public void testUnreflectSetter0() throws Throwable {
835 if (CAN_SKIP_WORKING) return;
836 startTest("unreflectSetter");
837 testSetter(TEST_UNREFLECT);
845 public void testFindSetter0() throws Throwable {
846 if (CAN_SKIP_WORKING) return;
847 startTest("findSetter");
848 testSetter(TEST_FIND_FIELD);
849 testSetter(TEST_FIND_FIELD | TEST_BOUND);
850 }
851
852 @Test
853 public void testFindStaticSetter() throws Throwable {
854 CodeCacheOverflowProcessor.runMHTest(this::testFindStaticSetter0);
855 }
856
857 public void testFindStaticSetter0() throws Throwable {
858 if (CAN_SKIP_WORKING) return;
859 startTest("findStaticSetter");
860 testSetter(TEST_FIND_STATIC);
861 }
862
863 public void testSetter(int testMode) throws Throwable {
864 Lookup lookup = PRIVATE; // FIXME: test more lookups than this one
865 startTest("unreflectSetter");
866 for (Object[] c : HasFields.CASES) {
867 boolean positive = (c[1] != Error.class);
868 testSetter(positive, lookup, c[0], c[1], testMode);
869 if (positive)
870 testSetter(positive, lookup, c[0], c[1], testMode | TEST_NPE);
871 }
872 for (int isStaticN = 0; isStaticN <= 1; isStaticN++) {
873 testSetter(false, lookup,
874 new Object[]{ (isStaticN != 0), System.class, "bogus", char.class },
875 null, testMode);
876 }
877 }
878
879 public void testSetter(boolean positive, MethodHandles.Lookup lookup,
880 Object fieldRef, Object value, int testMode) throws Throwable {
881 testAccessor(positive, lookup, fieldRef, value, testMode | TEST_SETTER);
882 }
883
884 @Test
885 public void testArrayElementGetter() throws Throwable {
|
647 testGetter(false, lookup,
648 new Object[]{ (isStaticN != 0), System.class, "bogus", char.class },
649 null, testMode);
650 }
651 }
652
653 public void testGetter(boolean positive, MethodHandles.Lookup lookup,
654 Object fieldRef, Object value, int testMode) throws Throwable {
655 testAccessor(positive, lookup, fieldRef, value, testMode);
656 }
657
658 public void testAccessor(boolean positive0, MethodHandles.Lookup lookup,
659 Object fieldRef, Object value, int testMode0) throws Throwable {
660 if (verbosity >= 4)
661 System.out.println("testAccessor"+Arrays.deepToString(new Object[]{positive0, lookup, fieldRef, value, testMode0}));
662 boolean isGetter = ((testMode0 & TEST_SETTER) == 0);
663 boolean doBound = ((testMode0 & TEST_BOUND) != 0);
664 boolean testNPE = ((testMode0 & TEST_NPE) != 0);
665 int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE);
666 boolean positive = positive0 && !testNPE;
667 boolean isFinal;
668 boolean isStatic;
669 Class<?> fclass;
670 String fname;
671 Class<?> ftype;
672 Field f = (fieldRef instanceof Field ? (Field)fieldRef : null);
673 if (f != null) {
674 isStatic = Modifier.isStatic(f.getModifiers());
675 isFinal = Modifier.isFinal(f.getModifiers());
676 fclass = f.getDeclaringClass();
677 fname = f.getName();
678 ftype = f.getType();
679 } else {
680 Object[] scnt = (Object[]) fieldRef;
681 isStatic = (Boolean) scnt[0];
682 isFinal = false;
683 fclass = (Class<?>) scnt[1];
684 fname = (String) scnt[2];
685 ftype = (Class<?>) scnt[3];
686 try {
687 f = fclass.getDeclaredField(fname);
688 } catch (ReflectiveOperationException ex) {
689 f = null;
690 }
691 }
692 if (!testModeMatches(testMode, isStatic)) return;
693 if (f == null && testMode == TEST_UNREFLECT) return;
694 if (testNPE && isStatic) return;
695 countTest(positive);
696 MethodType expType;
697 if (isGetter)
698 expType = MethodType.methodType(ftype, HasFields.class);
699 else
700 expType = MethodType.methodType(void.class, HasFields.class, ftype);
701 if (isStatic) expType = expType.dropParameterTypes(0, 1);
702 Exception noAccess = null;
706 case TEST_UNREFLECT: mh = lookup.unreflectGetter(f); break;
707 case TEST_FIND_FIELD: mh = lookup.findGetter(fclass, fname, ftype); break;
708 case TEST_FIND_STATIC: mh = lookup.findStaticGetter(fclass, fname, ftype); break;
709 case TEST_SETTER|
710 TEST_UNREFLECT: mh = lookup.unreflectSetter(f); break;
711 case TEST_SETTER|
712 TEST_FIND_FIELD: mh = lookup.findSetter(fclass, fname, ftype); break;
713 case TEST_SETTER|
714 TEST_FIND_STATIC: mh = lookup.findStaticSetter(fclass, fname, ftype); break;
715 default:
716 throw new InternalError("testMode="+testMode);
717 }
718 } catch (ReflectiveOperationException ex) {
719 mh = null;
720 noAccess = ex;
721 assertExceptionClass(
722 (fname.contains("bogus"))
723 ? NoSuchFieldException.class
724 : IllegalAccessException.class,
725 noAccess);
726 if (((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic)) return; // Final static field setter test failed as intended.
727 if (verbosity >= 5) ex.printStackTrace(System.out);
728 }
729 if (verbosity >= 3)
730 System.out.println((((testMode0 & TEST_UNREFLECT) != 0)?"unreflect":"find")
731 +(((testMode0 & TEST_FIND_STATIC) != 0)?"Static":"")
732 +(isGetter?"Getter":"Setter")
733 +" "+fclass.getName()+"."+fname+"/"+ftype
734 +" => "+mh
735 +(noAccess == null ? "" : " !! "+noAccess));
736 if (positive && !testNPE && noAccess != null) throw new RuntimeException(noAccess);
737 assertEquals(positive0 ? "positive test" : "negative test erroneously passed", positive0, mh != null);
738 assertFalse("Setter methods should throw an exception if passed a final static field.", ((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic));
739 if (!positive && !testNPE) return; // negative access test failed as expected
740 assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount());
741 assertSame(mh.type(), expType);
742 //assertNameStringContains(mh, fname); // This does not hold anymore with LFs
743 HasFields fields = new HasFields();
744 HasFields fieldsForMH = fields;
745 if (testNPE) fieldsForMH = null; // perturb MH argument to elicit expected error
746 if (doBound)
747 mh = mh.bindTo(fieldsForMH);
748 Object sawValue;
749 Class<?> vtype = ftype;
750 if (ftype != int.class) vtype = Object.class;
751 if (isGetter) {
752 mh = mh.asType(mh.type().generic()
753 .changeReturnType(vtype));
754 } else {
755 int last = mh.type().parameterCount() - 1;
756 mh = mh.asType(mh.type().generic()
757 .changeReturnType(void.class)
758 .changeParameterType(last, vtype));
759 }
760 if (f != null && f.getDeclaringClass() == HasFields.class) {
767 sawValue = null; // make DA rules happy under try/catch
768 try {
769 if (isStatic || doBound) {
770 if (ftype == int.class)
771 sawValue = (int) mh.invokeExact(); // do these exactly
772 else
773 sawValue = mh.invokeExact();
774 } else {
775 if (ftype == int.class)
776 sawValue = (int) mh.invokeExact((Object) fieldsForMH);
777 else
778 sawValue = mh.invokeExact((Object) fieldsForMH);
779 }
780 } catch (RuntimeException ex) {
781 if (ex instanceof NullPointerException && testNPE) {
782 caughtEx = ex;
783 break;
784 }
785 }
786 assertEquals(sawValue, expValue);
787 if (f != null && f.getDeclaringClass() == HasFields.class && !isFinal) {
788 Object random = randomArg(ftype);
789 f.set(fields, random);
790 expValue = random;
791 } else {
792 break;
793 }
794 }
795 } else {
796 for (int i = 0; i <= 1; i++) {
797 Object putValue = randomArg(ftype);
798 try {
799 if (isStatic || doBound) {
800 if (ftype == int.class)
801 mh.invokeExact((int)putValue); // do these exactly
802 else
803 mh.invokeExact(putValue);
804 } else {
805 if (ftype == int.class)
806 mh.invokeExact((Object) fieldsForMH, (int)putValue);
807 else
808 mh.invokeExact((Object) fieldsForMH, putValue);
809 }
810 } catch (RuntimeException ex) {
811 if (ex instanceof NullPointerException && testNPE) {
812 caughtEx = ex;
813 break;
814 }
815 }
816 if (f != null && f.getDeclaringClass() == HasFields.class) {
817 assertEquals(f.get(fields), putValue);
818 }
819 }
820 }
821 if ((f != null) && (f.getDeclaringClass() == HasFields.class) && !isFinal) {
822 f.set(fields, value); // put it back if we changed it.
823 }
824 if (testNPE) {
825 if (caughtEx == null || !(caughtEx instanceof NullPointerException))
826 throw new RuntimeException("failed to catch NPE exception"+(caughtEx == null ? " (caughtEx=null)" : ""), caughtEx);
827 caughtEx = null; // nullify expected exception
828 }
829 if (caughtEx != null) {
830 throw new RuntimeException("unexpected exception", caughtEx);
831 }
832 }
833
834 @Test
835 public void testUnreflectSetter() throws Throwable {
836 CodeCacheOverflowProcessor.runMHTest(this::testUnreflectSetter0);
837 }
838
839 public void testUnreflectSetter0() throws Throwable {
840 if (CAN_SKIP_WORKING) return;
841 startTest("unreflectSetter");
842 testSetter(TEST_UNREFLECT);
850 public void testFindSetter0() throws Throwable {
851 if (CAN_SKIP_WORKING) return;
852 startTest("findSetter");
853 testSetter(TEST_FIND_FIELD);
854 testSetter(TEST_FIND_FIELD | TEST_BOUND);
855 }
856
857 @Test
858 public void testFindStaticSetter() throws Throwable {
859 CodeCacheOverflowProcessor.runMHTest(this::testFindStaticSetter0);
860 }
861
862 public void testFindStaticSetter0() throws Throwable {
863 if (CAN_SKIP_WORKING) return;
864 startTest("findStaticSetter");
865 testSetter(TEST_FIND_STATIC);
866 }
867
868 public void testSetter(int testMode) throws Throwable {
869 Lookup lookup = PRIVATE; // FIXME: test more lookups than this one
870 for (Object[] c : HasFields.CASES) {
871 boolean positive = (c[1] != Error.class);
872 testSetter(positive, lookup, c[0], c[1], testMode);
873 if (positive)
874 testSetter(positive, lookup, c[0], c[1], testMode | TEST_NPE);
875 }
876 for (int isStaticN = 0; isStaticN <= 1; isStaticN++) {
877 testSetter(false, lookup,
878 new Object[]{ (isStaticN != 0), System.class, "bogus", char.class },
879 null, testMode);
880 }
881 }
882
883 public void testSetter(boolean positive, MethodHandles.Lookup lookup,
884 Object fieldRef, Object value, int testMode) throws Throwable {
885 testAccessor(positive, lookup, fieldRef, value, testMode | TEST_SETTER);
886 }
887
888 @Test
889 public void testArrayElementGetter() throws Throwable {
|