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