1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @modules jdk.incubator.code
27 * @run junit TestTry
28 * @run main Unreflect TestTry
29 * @run junit TestTry
30 */
31
32 import jdk.incubator.code.Reflect;
33 import jdk.incubator.code.CodeTransformer;
34 import jdk.incubator.code.Op;
35 import jdk.incubator.code.dialect.core.CoreOp;
36 import jdk.incubator.code.interpreter.Interpreter;
37 import org.junit.jupiter.api.Assertions;
38 import org.junit.jupiter.api.Test;
39
40 import java.lang.invoke.MethodHandles;
41 import java.lang.reflect.Method;
42 import java.util.ArrayList;
43 import java.util.List;
44 import java.util.Optional;
45 import java.util.function.Consumer;
46 import java.util.function.IntConsumer;
47 import java.util.stream.Stream;
48
49 public class TestTry {
50
51 @Reflect
52 public static void catching(IntConsumer c) {
53 try {
54 c.accept(0);
55 c.accept(-1);
56 } catch (IllegalStateException e) {
57 consume(e);
58 c.accept(1);
59 c.accept(-1);
60 } catch (IllegalArgumentException e) {
61 consume(e);
62 c.accept(2);
63 c.accept(-1);
64 }
65 c.accept(3);
66 c.accept(-1);
67 }
68
69 @Test
70 public void testCatching() {
71 CoreOp.FuncOp f = getFuncOp("catching");
72
73 System.out.println(f.toText());
74
75 CoreOp.FuncOp lf = f.transform(CodeTransformer.LOWERING_TRANSFORMER);
76
77 System.out.println(lf.toText());
78
79 Consumer<IntConsumer> test = testConsumer(
80 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c),
81 TestTry::catching);
82
83 test.accept(i -> {
84 });
85 test.accept(i -> {
86 if (i == 0) throw new IllegalStateException();
87 });
88 test.accept(i -> {
89 if (i == 0) throw new IllegalArgumentException();
90 });
91 test.accept(i -> {
92 if (i == 0) throw new NullPointerException();
93 });
94 test.accept(i -> {
95 if (i == 0) throw new IllegalStateException();
96 if (i == 1) throw new RuntimeException();
97 });
98 test.accept(i -> {
99 if (i == 0) throw new IllegalArgumentException();
100 if (i == 2) throw new RuntimeException();
101 });
102 test.accept(i -> {
103 if (i == 3) throw new IllegalStateException();
104 });
105 }
106
107
108 @Reflect
109 public static void catchThrowable(IntConsumer c) {
110 try {
111 c.accept(0);
112 c.accept(-1);
113 } catch (IllegalStateException e) {
114 consume(e);
115 c.accept(1);
116 c.accept(-1);
117 } catch (Throwable e) {
118 consume(e);
119 c.accept(2);
120 c.accept(-1);
121 }
122 c.accept(3);
123 c.accept(-1);
124 }
125
126 @Test
127 public void testCatchThrowable() {
128 CoreOp.FuncOp f = getFuncOp("catchThrowable");
129
130 System.out.println(f.toText());
131
132 CoreOp.FuncOp lf = f.transform(CodeTransformer.LOWERING_TRANSFORMER);
133
134 System.out.println(lf.toText());
135
136 Consumer<IntConsumer> test = testConsumer(
137 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c),
138 TestTry::catchThrowable);
139
140 test.accept(i -> {
141 });
142 test.accept(i -> {
143 if (i == 0) throw new IllegalStateException();
144 });
145 test.accept(i -> {
146 if (i == 0) throw new RuntimeException();
147 });
148 test.accept(i -> {
149 if (i == 0) throw new IllegalStateException();
150 if (i == 1) throw new RuntimeException();
151 });
152 test.accept(i -> {
153 if (i == 0) throw new RuntimeException();
154 if (i == 2) throw new RuntimeException();
155 });
156 test.accept(i -> {
157 if (i == 3) throw new IllegalStateException();
158 });
159 }
160
161
162 @Reflect
163 public static void catchNested(IntConsumer c) {
164 try {
165 c.accept(0);
166 c.accept(-1);
167 try {
168 c.accept(1);
169 c.accept(-1);
170 } catch (IllegalStateException e) {
171 consume(e);
172 c.accept(2);
173 c.accept(-1);
174 }
175 c.accept(3);
176 c.accept(-1);
177 } catch (IllegalArgumentException e) {
178 consume(e);
179 c.accept(4);
180 c.accept(-1);
181 }
182 c.accept(5);
183 c.accept(-1);
184 }
185
186 @Test
187 public void testCatchNested() {
188 CoreOp.FuncOp f = getFuncOp("catchNested");
189
190 System.out.println(f.toText());
191
192 CoreOp.FuncOp lf = f.transform(CodeTransformer.LOWERING_TRANSFORMER);
193
194 System.out.println(lf.toText());
195
196 Consumer<IntConsumer> test = testConsumer(
197 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c),
198 TestTry::catchNested);
199
200 test.accept(i -> {
201 });
202 test.accept(i -> {
203 if (i == 0) throw new IllegalStateException();
204 });
205 test.accept(i -> {
206 if (i == 0) throw new IllegalArgumentException();
207 });
208 test.accept(i -> {
209 if (i == 1) throw new IllegalStateException();
210 });
211 test.accept(i -> {
212 if (i == 1) throw new IllegalArgumentException();
213 });
214 test.accept(i -> {
215 if (i == 1) throw new IllegalStateException();
216 if (i == 2) throw new IllegalArgumentException();
217 });
218 test.accept(i -> {
219 if (i == 1) throw new IllegalStateException();
220 if (i == 2) throw new RuntimeException();
221 });
222 test.accept(i -> {
223 if (i == 3) throw new IllegalArgumentException();
224 });
225 test.accept(i -> {
226 if (i == 3) throw new RuntimeException();
227 });
228 test.accept(i -> {
229 if (i == 3) throw new IllegalArgumentException();
230 if (i == 4) throw new RuntimeException();
231 });
232 test.accept(i -> {
233 if (i == 5) throw new RuntimeException();
234 });
235 }
236
237
238 static CoreOp.FuncOp getFuncOp(String name) {
239 Optional<Method> om = Stream.of(TestTry.class.getDeclaredMethods())
240 .filter(m -> m.getName().equals(name))
241 .findFirst();
242
243 Method m = om.get();
244 return Op.ofMethod(m).get();
245 }
246
247 static void consume(Throwable e) {
248 }
249
250 static Consumer<IntConsumer> testConsumer(Consumer<IntConsumer> actualR, Consumer<IntConsumer> expectedR) {
251 return c -> {
252 List<Integer> actual = new ArrayList<>();
253 IntConsumer actualC = actual::add;
254 Throwable actualT = null;
255 try {
256 actualR.accept(actualC.andThen(c));
257 } catch (Interpreter.InterpreterException e) {
258 throw e;
259 } catch (Throwable t) {
260 actualT = t;
261 if (t instanceof AssertionError) {
262 t.printStackTrace();
263 }
264 }
265
266 List<Integer> expected = new ArrayList<>();
267 IntConsumer expectedC = expected::add;
268 Throwable expectedT = null;
269 try {
270 expectedR.accept(expectedC.andThen(c));
271 } catch (Throwable t) {
272 expectedT = t;
273 }
274
275 Assertions.assertEquals(
276 expectedT != null ? expectedT.getClass() : null, actualT != null ? actualT.getClass() : null
277 );
278 Assertions.assertEquals(expected, actual);
279 };
280 }
281 }