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 testng TestTryNested 28 */ 29 30 import jdk.incubator.code.Op; 31 import org.testng.Assert; 32 import org.testng.annotations.Test; 33 34 import jdk.incubator.code.OpTransformer; 35 import jdk.incubator.code.op.CoreOp; 36 import jdk.incubator.code.interpreter.Interpreter; 37 import java.lang.invoke.MethodHandles; 38 import java.lang.reflect.Method; 39 import jdk.incubator.code.CodeReflection; 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 f.writeTo(System.out); 90 91 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 92 93 lf.writeTo(System.out); 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 f.writeTo(System.out); 149 150 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 151 152 lf.writeTo(System.out); 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 f.writeTo(System.out); 217 218 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 219 220 lf.writeTo(System.out); 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 f.writeTo(System.out); 268 269 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 270 271 lf.writeTo(System.out); 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 f.writeTo(System.out); 314 315 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 316 317 lf.writeTo(System.out); 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 f.writeTo(System.out); 366 367 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 368 369 lf.writeTo(System.out); 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 f.writeTo(System.out); 405 406 CoreOp.FuncOp lf = f.transform(OpTransformer.LOWERING_TRANSFORMER); 407 408 lf.writeTo(System.out); 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 Assert.assertEquals( 456 actualT != null ? actualT.getClass() : null, 457 expectedT != null ? expectedT.getClass() : null); 458 Assert.assertEquals(actual, expected); 459 }; 460 } 461 }