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