732 return SELECT_ALTERNATIVE; 733 } 734 735 static 736 MethodHandle makeGuardWithTest(MethodHandle test, 737 MethodHandle target, 738 MethodHandle fallback) { 739 // gwt(arg...) 740 // [fold]=> continueAfterTest(z=test(arg...), arg...) 741 // [filter]=> (tf=select(z))(arg...) 742 // where select(z) = select(z, t, f).bindTo(t, f) => z ? t f 743 // [tailcall]=> tf(arg...) 744 assert(test.type().returnType() == boolean.class); 745 MethodType targetType = target.type(); 746 MethodType foldTargetType = targetType.insertParameterTypes(0, boolean.class); 747 assert(AdapterMethodHandle.canCollectArguments(foldTargetType, test.type(), 0, true)); 748 // working backwards, as usual: 749 assert(target.type().equals(fallback.type())); 750 MethodHandle tailcall = MethodHandles.exactInvoker(target.type()); 751 MethodHandle select = selectAlternative(); 752 select = bindArgument(select, 2, fallback); 753 select = bindArgument(select, 1, target); 754 // select(z: boolean) => (z ? target : fallback) 755 MethodHandle filter = filterArgument(tailcall, 0, select); 756 assert(filter.type().parameterType(0) == boolean.class); 757 MethodHandle fold = foldArguments(filter, filter.type().dropParameterTypes(0, 1), 0, test); 758 return fold; 759 } 760 761 private static class GuardWithCatch extends BoundMethodHandle { 762 private final MethodHandle target; 763 private final Class<? extends Throwable> exType; 764 private final MethodHandle catcher; 765 GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { 766 this(INVOKES[target.type().parameterCount()], target, exType, catcher); 767 } 768 // FIXME: Build the control flow out of foldArguments. 769 GuardWithCatch(MethodHandle invoker, 770 MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { 771 super(invoker); 772 this.target = target; 773 this.exType = exType; | 732 return SELECT_ALTERNATIVE; 733 } 734 735 static 736 MethodHandle makeGuardWithTest(MethodHandle test, 737 MethodHandle target, 738 MethodHandle fallback) { 739 // gwt(arg...) 740 // [fold]=> continueAfterTest(z=test(arg...), arg...) 741 // [filter]=> (tf=select(z))(arg...) 742 // where select(z) = select(z, t, f).bindTo(t, f) => z ? t f 743 // [tailcall]=> tf(arg...) 744 assert(test.type().returnType() == boolean.class); 745 MethodType targetType = target.type(); 746 MethodType foldTargetType = targetType.insertParameterTypes(0, boolean.class); 747 assert(AdapterMethodHandle.canCollectArguments(foldTargetType, test.type(), 0, true)); 748 // working backwards, as usual: 749 assert(target.type().equals(fallback.type())); 750 MethodHandle tailcall = MethodHandles.exactInvoker(target.type()); 751 MethodHandle select = selectAlternative(); 752 select = bindArgument(select, 2, CountingMethodHandle.wrap(fallback)); 753 select = bindArgument(select, 1, CountingMethodHandle.wrap(target)); 754 // select(z: boolean) => (z ? target : fallback) 755 MethodHandle filter = filterArgument(tailcall, 0, select); 756 assert(filter.type().parameterType(0) == boolean.class); 757 MethodHandle fold = foldArguments(filter, filter.type().dropParameterTypes(0, 1), 0, test); 758 return fold; 759 } 760 761 private static class GuardWithCatch extends BoundMethodHandle { 762 private final MethodHandle target; 763 private final Class<? extends Throwable> exType; 764 private final MethodHandle catcher; 765 GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { 766 this(INVOKES[target.type().parameterCount()], target, exType, catcher); 767 } 768 // FIXME: Build the control flow out of foldArguments. 769 GuardWithCatch(MethodHandle invoker, 770 MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) { 771 super(invoker); 772 this.target = target; 773 this.exType = exType; |