1 import jdk.incubator.code.Block;
2 import jdk.incubator.code.CodeTransformer;
3 import jdk.incubator.code.Op;
4 import jdk.incubator.code.Reflect;
5 import jdk.incubator.code.Value;
6 import jdk.incubator.code.dialect.core.CoreOp;
7 import jdk.incubator.code.dialect.core.Inliner;
8 import jdk.incubator.code.dialect.java.JavaOp;
9 import org.junit.jupiter.api.Assertions;
10 import org.junit.jupiter.api.Test;
11
12 import java.lang.invoke.MethodHandles;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.function.BiConsumer;
16 import java.util.function.Consumer;
17 import java.util.function.IntConsumer;
18
19 /*
20 * @test
21 * @modules jdk.incubator.code
22 * @library lib
23 * @run junit TestTryOpWithExceptionRegion
24 * @run junit/othervm -Dbabylon.tryFinally=sharedDispatch TestTryOpWithExceptionRegion
25 * @run main Unreflect TestTryOpWithExceptionRegion
26 * @run junit TestTryOpWithExceptionRegion
27 * @run junit/othervm -Dbabylon.tryFinally=sharedDispatch TestTryOpWithExceptionRegion
28 */
29 public class TestTryOpWithExceptionRegion {
30 @Reflect
31 static void m(IntConsumer c) {
32 try {
33 c.accept(0);
34 n(c);
35 } catch (IllegalArgumentException ex) {
36 c.accept(4);
37 } finally {
38 c.accept(5);
39 }
40 }
41
42 @Reflect
43 private static void n(IntConsumer c) {
44 try {
45 c.accept(1);
46 } catch (IllegalStateException ex) {
47 c.accept(2);
48 } finally {
49 c.accept(3);
50 }
51 }
52
53 BiConsumer<Block.Builder, Value> IGNORE_RETURN = (rb, rv) -> {};
54 @Test
55 void testTryOpEnclosingExceptionRegion() throws NoSuchMethodException {
56 // lower n + inline it in m
57 CoreOp.FuncOp n = Op.ofMethod(this.getClass().getDeclaredMethod("n", IntConsumer.class)).get();
58 CoreOp.FuncOp ln = n.transform(CodeTransformer.LOWERING_TRANSFORMER);
59 CoreOp.FuncOp m = Op.ofMethod(this.getClass().getDeclaredMethod("m", IntConsumer.class)).get();
60 CoreOp.FuncOp m2 = m.transform((b, o) -> {
61 if (o instanceof JavaOp.InvokeOp iop && iop.invokeReference().name().equals("n")) {
62 return Inliner.inline(b, ln, b.context().getValues(m.parameters()), IGNORE_RETURN);
63 } else {
64 b.add(o);
65 return b;
66 }
67 });
68 System.out.println(m2.toText());
69
70 Consumer<IntConsumer> test = testConsumer(
71 c -> Interpreter.invoke(MethodHandles.lookup(), m2, c),
72 TestTryOpWithExceptionRegion::m
73 );
74 test.accept(i -> {
75 if (i == 1) throw new IllegalStateException();
76 });
77
78 test.accept(i -> {
79 if (i == 1) throw new IllegalArgumentException();
80 });
81 }
82
83 @Test
84 void testTryOpEnclosedByExceptionRegion() throws NoSuchMethodException {
85 // lower m + inline n
86 CoreOp.FuncOp m = Op.ofMethod(this.getClass().getDeclaredMethod("m", IntConsumer.class)).get();
87 CoreOp.FuncOp lm = m.transform(CodeTransformer.LOWERING_TRANSFORMER);
88 CoreOp.FuncOp n = Op.ofMethod(this.getClass().getDeclaredMethod("n", IntConsumer.class)).get();
89 CoreOp.FuncOp lm2 = lm.transform((b, o) -> {
90 if (o instanceof JavaOp.InvokeOp iop && iop.invokeReference().name().equals("n")) {
91 return Inliner.inline(b, n, b.context().getValues(lm.parameters()), IGNORE_RETURN);
92 } else {
93 b.add(o);
94 return b;
95 }
96 });
97
98 Consumer<IntConsumer> test = testConsumer(
99 c -> Interpreter.invoke(MethodHandles.lookup(), lm2, c),
100 TestTryOpWithExceptionRegion::m
101 );
102 test.accept(i -> {
103 if (i == 1) throw new IllegalStateException();
104 });
105
106 test.accept(i -> {
107 if (i == 1) throw new IllegalArgumentException();
108 });
109 }
110
111 static Consumer<IntConsumer> testConsumer(Consumer<IntConsumer> actualR, Consumer<IntConsumer> expectedR) {
112 return c -> {
113 List<Integer> actual = new ArrayList<>();
114 IntConsumer actualC = actual::add;
115 Throwable actualT = null;
116 try {
117 actualR.accept(actualC.andThen(c));
118 } catch (Interpreter.InterpreterException e) {
119 throw e;
120 } catch (Throwable t) {
121 actualT = t;
122 if (t instanceof AssertionError) {
123 t.printStackTrace();
124 }
125 }
126
127 List<Integer> expected = new ArrayList<>();
128 IntConsumer expectedC = expected::add;
129 Throwable expectedT = null;
130 try {
131 expectedR.accept(expectedC.andThen(c));
132 } catch (Throwable t) {
133 expectedT = t;
134 }
135
136 Assertions.assertEquals(
137 expectedT != null ? expectedT.getClass() : null, actualT != null ? actualT.getClass() : null
138 );
139 Assertions.assertEquals(expected, actual);
140 };
141 }
142 }