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