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