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 TestTryNested
28 */
29
30 import jdk.incubator.code.CodeReflection;
31 import jdk.incubator.code.Op;
32 import jdk.incubator.code.OpTransformer;
33 import jdk.incubator.code.dialect.core.CoreOp;
34 import jdk.incubator.code.interpreter.Interpreter;
35 import org.junit.jupiter.api.Assertions;
36 import org.junit.jupiter.api.Test;
37
38 import java.lang.invoke.MethodHandles;
39 import java.lang.reflect.Method;
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.Optional;
43 import java.util.function.Consumer;
44 import java.util.function.IntConsumer;
45 import java.util.stream.Stream;
46
47 public class TestTryNested {
48 @CodeReflection
49 public static void tryCatchFinally(IntConsumer c, int i) {
50 try {
51 try {
52 if (i == 0) {
53 return;
54 }
55 c.accept(0);
56 } catch (IllegalStateException e) {
57 if (i == 1) {
58 return;
59 }
60 c.accept(1);
61 } finally {
62 if (i == 2) {
63 return;
64 }
65 c.accept(2);
66 }
67 if (i == 3) {
68 return;
69 }
70 c.accept(3);
71 } catch (IllegalStateException e) {
72 if (i == 4) {
73 return;
74 }
75 c.accept(4);
76 } finally {
77 if (i == 5) {
78 return;
79 }
80 c.accept(5);
81 }
82 c.accept(6);
83 }
84
85 @Test
86 public void testCatchFinally() {
87 CoreOp.FuncOp f = getFuncOp("tryCatchFinally");
88
89 System.out.println(f.toText());
90
91 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER);
92
93 System.out.println(lf.toText());
94
95 for (int ra = -1; ra < 6; ra++) {
96 int fra = ra;
97
98 Consumer<IntConsumer> test = testConsumer(
99 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c, fra),
100 c -> tryCatchFinally(c, fra)
101 );
102
103 test.accept(i -> {});
104 for (int ea = 0; ea < 6; ea++) {
105 int fea = ea;
106 test.accept(i -> {
107 if (i == fea) throw new IllegalStateException();
108 });
109 test.accept(i -> {
110 if (i == fea) throw new RuntimeException();
111 });
112 }
113 }
114 }
115
116
117 @CodeReflection
118 public static void tryCatchBreak(IntConsumer c, int i) {
119 a: try {
120 try {
121 if (i == 0) {
122 break a;
123 }
124 c.accept(0);
125 } catch (IllegalStateException e) {
126 if (i == 1) {
127 break a;
128 }
129 c.accept(1);
130 }
131 if (i == 2) {
132 break a;
133 }
134 c.accept(2);
135 } catch (IllegalStateException e) {
136 if (i == 3) {
137 break a;
138 }
139 c.accept(3);
140 }
141 c.accept(4);
142 }
143
144 @Test
145 public void testCatchBreak() {
146 CoreOp.FuncOp f = getFuncOp("tryCatchBreak");
147
148 System.out.println(f.toText());
149
150 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER);
151
152 System.out.println(lf.toText());
153
154 for (int ra = -1; ra < 4; ra++) {
155 int fra = ra;
156
157 Consumer<IntConsumer> test = testConsumer(
158 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c, fra),
159 c -> tryCatchBreak(c, fra)
160 );
161
162 test.accept(i -> {});
163 for (int ea = 0; ea <= 4; ea++) {
164 int fea = ea;
165 test.accept(i -> {
166 if (i == fea) throw new IllegalStateException();
167 });
168 test.accept(i -> {
169 if (i == fea) throw new RuntimeException();
170 });
171 }
172 }
173 }
174
175 @CodeReflection
176 public static void tryCatchFinallyBreak(IntConsumer c, int i) {
177 a: try {
178 try {
179 if (i == 0) {
180 break a;
181 }
182 c.accept(0);
183 } catch (IllegalStateException e) {
184 if (i == 1) {
185 break a;
186 }
187 c.accept(1);
188 } finally {
189 if (i == 2) {
190 break a;
191 }
192 c.accept(2);
193 }
194 if (i == 3) {
195 break a;
196 }
197 c.accept(3);
198 } catch (IllegalStateException e) {
199 if (i == 4) {
200 break a;
201 }
202 c.accept(4);
203 } finally {
204 if (i == 5) {
205 break a;
206 }
207 c.accept(5);
208 }
209 c.accept(6);
210 }
211
212 @Test
213 public void testCatchFinallyBreak() {
214 CoreOp.FuncOp f = getFuncOp("tryCatchFinallyBreak");
215
216 System.out.println(f.toText());
217
218 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER);
219
220 System.out.println(lf.toText());
221
222 for (int ra = -1; ra < 6; ra++) {
223 int fra = ra;
224
225 Consumer<IntConsumer> test = testConsumer(
226 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c, fra),
227 c -> tryCatchFinallyBreak(c, fra)
228 );
229
230 test.accept(i -> {});
231 for (int ea = 0; ea <= 6; ea++) {
232 int fea = ea;
233 test.accept(i -> {
234 if (i == fea) throw new IllegalStateException();
235 });
236 test.accept(i -> {
237 if (i == fea) throw new RuntimeException();
238 });
239 }
240 }
241 }
242
243
244 @CodeReflection
245 public static void tryForLoop(IntConsumer c) {
246 for (int i = 0; i < 8; i++) {
247 c.accept(0);
248 try {
249 if (i == 4) {
250 continue;
251 } else if (i == 5) {
252 break;
253 }
254 c.accept(1);
255 } catch (IllegalStateException e) {
256 c.accept(2);
257 }
258 c.accept(3);
259 }
260 c.accept(4);
261 }
262
263 @Test
264 public void testTryForLoop() {
265 CoreOp.FuncOp f = getFuncOp("tryForLoop");
266
267 System.out.println(f.toText());
268
269 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER);
270
271 System.out.println(lf.toText());
272
273 Consumer<IntConsumer> test = testConsumer(
274 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c),
275 TestTryNested::tryForLoop
276 );
277
278 test.accept(i -> { });
279 for (int ea = 0; ea <= 4; ea++) {
280 int fea = ea;
281 test.accept(i -> {
282 if (i == fea) throw new IllegalStateException();
283 });
284 test.accept(i -> {
285 if (i == fea) throw new RuntimeException();
286 });
287 }
288 }
289
290 @CodeReflection
291 public static void tryForLoopFinally(IntConsumer c) {
292 for (int i = 0; i < 8; i++) {
293 c.accept(0);
294 try {
295 if (i == 4) {
296 continue;
297 } else if (i == 5) {
298 break;
299 }
300 c.accept(1);
301 } finally {
302 c.accept(2);
303 }
304 c.accept(3);
305 }
306 c.accept(4);
307 }
308
309 @Test
310 public void testTryForLoopFinally() {
311 CoreOp.FuncOp f = getFuncOp("tryForLoopFinally");
312
313 System.out.println(f.toText());
314
315 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER);
316
317 System.out.println(lf.toText());
318
319 Consumer<IntConsumer> test = testConsumer(
320 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c),
321 TestTryNested::tryForLoopFinally
322 );
323
324 test.accept(i -> { });
325 for (int ea = 0; ea <= 4; ea++) {
326 int fea = ea;
327 test.accept(i -> {
328 if (i == fea) throw new IllegalStateException();
329 });
330 test.accept(i -> {
331 if (i == fea) throw new RuntimeException();
332 });
333 }
334 }
335
336
337 @CodeReflection
338 public static void tryLabeledForLoop(IntConsumer c) {
339 a: for (int i = 0; i < 8; i++) {
340 c.accept(0);
341 b: {
342 try {
343 if (i == 4) {
344 continue a;
345 } else if (i == 5) {
346 break b;
347 } else if (i == 6) {
348 break a;
349 }
350 c.accept(1);
351 } finally {
352 c.accept(2);
353 }
354 c.accept(3);
355 }
356 c.accept(4);
357 }
358 c.accept(5);
359 }
360
361 @Test
362 public void testTryLabeledForLoop() {
363 CoreOp.FuncOp f = getFuncOp("tryLabeledForLoop");
364
365 System.out.println(f.toText());
366
367 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER);
368
369 System.out.println(lf.toText());
370
371 Consumer<IntConsumer> test = testConsumer(
372 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c),
373 TestTryNested::tryLabeledForLoop
374 );
375
376 test.accept(i -> { });
377 }
378
379
380 @CodeReflection
381 public static void tryLambda(IntConsumer c, int i) {
382 try {
383 c.accept(0);
384 Runnable r = () -> {
385 if (i == 0) {
386 c.accept(1);
387 return;
388 } else {
389 c.accept(2);
390 }
391 c.accept(3);
392 };
393 r.run();
394 c.accept(4);
395 } finally {
396 c.accept(5);
397 }
398 }
399
400 @Test
401 public void testTryLambda() {
402 CoreOp.FuncOp f = getFuncOp("tryLambda");
403
404 System.out.println(f.toText());
405
406 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER);
407
408 System.out.println(lf.toText());
409
410 for (int ra = 0; ra < 2; ra++) {
411 final int fra = ra;
412 Consumer<IntConsumer> test = testConsumer(
413 c -> Interpreter.invoke(MethodHandles.lookup(), lf, c, fra),
414 c -> tryLambda(c, fra)
415 );
416 test.accept(i -> { });
417 }
418 }
419
420
421 static CoreOp.FuncOp getFuncOp(String name) {
422 Optional<Method> om = Stream.of(TestTryNested.class.getDeclaredMethods())
423 .filter(m -> m.getName().equals(name))
424 .findFirst();
425
426 Method m = om.get();
427 return Op.ofMethod(m).get();
428 }
429
430 static Consumer<IntConsumer> testConsumer(Consumer<IntConsumer> actualR, Consumer<IntConsumer> expectedR) {
431 return c -> {
432 List<Integer> actual = new ArrayList<>();
433 IntConsumer actualC = actual::add;
434 Throwable actualT = null;
435 try {
436 actualR.accept(actualC.andThen(c));
437 } catch (Interpreter.InterpreterException e) {
438 throw e;
439 } catch (Throwable t) {
440 actualT = t;
441 if (t instanceof AssertionError) {
442 t.printStackTrace();
443 }
444 }
445
446 List<Integer> expected = new ArrayList<>();
447 IntConsumer expectedC = expected::add;
448 Throwable expectedT = null;
449 try {
450 expectedR.accept(expectedC.andThen(c));
451 } catch (Throwable t) {
452 expectedT = t;
453 }
454
455 Assertions.assertEquals(
456 expectedT != null ? expectedT.getClass() : null, actualT != null ? actualT.getClass() : null
457 );
458 Assertions.assertEquals(expected, actual);
459 };
460 }
461 }