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 @Test
54 void testTryOpEnclosingExceptionRegion() throws NoSuchMethodException {
55 // lower n + inline it in m
56 CoreOp.FuncOp n = Op.ofMethod(this.getClass().getDeclaredMethod("n", IntConsumer.class)).get();
57 CoreOp.FuncOp ln = n.transform(CodeTransformer.LOWERING_TRANSFORMER);
58 CoreOp.FuncOp m = Op.ofMethod(this.getClass().getDeclaredMethod("m", IntConsumer.class)).get();
59 CoreOp.FuncOp m2 = m.transform((b, o) -> {
60 if (o instanceof JavaOp.InvokeOp iop && iop.invokeReference().name().equals("n")) {
61 return Inliner.inline(b, ln, b.context().getValues(m.parameters()));
62 } else {
63 b.add(o);
64 return b;
65 }
66 });
67 System.out.println(m2.toText());
68
69 Consumer<IntConsumer> test = testConsumer(
70 c -> Interpreter.invoke(MethodHandles.lookup(), m2, c),
71 TestTryOpWithExceptionRegion::m
72 );
73 test.accept(i -> {
74 if (i == 1) throw new IllegalStateException();
75 });
76
77 test.accept(i -> {
78 if (i == 1) throw new IllegalArgumentException();
79 });
80 }
81
82 @Test
83 void testTryOpEnclosedByExceptionRegion() throws NoSuchMethodException {
84 // lower m + inline n
85 CoreOp.FuncOp m = Op.ofMethod(this.getClass().getDeclaredMethod("m", IntConsumer.class)).get();
86 CoreOp.FuncOp lm = m.transform(CodeTransformer.LOWERING_TRANSFORMER);
87 CoreOp.FuncOp n = Op.ofMethod(this.getClass().getDeclaredMethod("n", IntConsumer.class)).get();
88 CoreOp.FuncOp lm2 = lm.transform((b, o) -> {
89 if (o instanceof JavaOp.InvokeOp iop && iop.invokeReference().name().equals("n")) {
90 return Inliner.inline(b, n, b.context().getValues(lm.parameters()));
91 } else {
92 b.add(o);
93 return b;
94 }
95 });
96
97 Consumer<IntConsumer> test = testConsumer(
98 c -> Interpreter.invoke(MethodHandles.lookup(), lm2, c),
99 TestTryOpWithExceptionRegion::m
100 );
101 test.accept(i -> {
102 if (i == 1) throw new IllegalStateException();
103 });
104
105 test.accept(i -> {
106 if (i == 1) throw new IllegalArgumentException();
107 });
108 }
109
110 static Consumer<IntConsumer> testConsumer(Consumer<IntConsumer> actualR, Consumer<IntConsumer> expectedR) {
111 return c -> {
112 List<Integer> actual = new ArrayList<>();
113 IntConsumer actualC = actual::add;
114 Throwable actualT = null;
115 try {
116 actualR.accept(actualC.andThen(c));
117 } catch (Interpreter.InterpreterException e) {
118 throw e;
119 } catch (Throwable t) {
120 actualT = t;
121 if (t instanceof AssertionError) {
122 t.printStackTrace();
123 }
124 }
125
126 List<Integer> expected = new ArrayList<>();
127 IntConsumer expectedC = expected::add;
128 Throwable expectedT = null;
129 try {
130 expectedR.accept(expectedC.andThen(c));
131 } catch (Throwable t) {
132 expectedT = t;
133 }
134
135 Assertions.assertEquals(
136 expectedT != null ? expectedT.getClass() : null, actualT != null ? actualT.getClass() : null
137 );
138 Assertions.assertEquals(expected, actual);
139 };
140 }
141 }