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 import jdk.incubator.code.CodeReflection; 25 import java.util.List; 26 27 /* 28 * @test 29 * @summary Smoke test for code reflection with for loops. 30 * @modules jdk.incubator.code 31 * @build ForLoopTest 32 * @build CodeReflectionTester 33 * @run main CodeReflectionTester ForLoopTest 34 */ 35 36 public class ForLoopTest { 37 @CodeReflection 38 @IR(""" 39 func @"test1" (%0 : java.type:"ForLoopTest", %1 : java.type:"java.util.List<java.util.List<java.lang.String>>")java.type:"void" -> { 40 %2 : Var<java.type:"java.util.List<java.util.List<java.lang.String>>"> = var %1 @"ll"; 41 java.enhancedFor 42 ()java.type:"java.util.List<java.util.List<java.lang.String>>" -> { 43 %3 : java.type:"java.util.List<java.util.List<java.lang.String>>" = var.load %2; 44 yield %3; 45 } 46 (%4 : java.type:"java.util.List<java.lang.String>")Var<java.type:"java.util.List<java.lang.String>"> -> { 47 %5 : Var<java.type:"java.util.List<java.lang.String>"> = var %4 @"l"; 48 yield %5; 49 } 50 (%6 : Var<java.type:"java.util.List<java.lang.String>">)java.type:"void" -> { 51 java.enhancedFor 52 ()java.type:"java.util.List<java.lang.String>" -> { 53 %7 : java.type:"java.util.List<java.lang.String>" = var.load %6; 54 yield %7; 55 } 56 (%8 : java.type:"java.lang.String")Var<java.type:"java.lang.String"> -> { 57 %9 : Var<java.type:"java.lang.String"> = var %8 @"s"; 58 yield %9; 59 } 60 (%10 : Var<java.type:"java.lang.String">)java.type:"void" -> { 61 %11 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 62 %12 : java.type:"java.lang.String" = var.load %10; 63 invoke %11 %12 @java.ref:"java.io.PrintStream::println(java.lang.String):void"; 64 java.continue; 65 }; 66 java.continue; 67 }; 68 return; 69 }; 70 """) 71 void test1(List<List<String>> ll) { 72 for (List<String> l : ll) { 73 for (String s : l) { 74 System.out.println(s); 75 } 76 } 77 } 78 79 @CodeReflection 80 @IR(""" 81 func @"test2" (%0 : java.type:"ForLoopTest", %1 : java.type:"java.util.List<java.lang.String>")java.type:"void" -> { 82 %2 : Var<java.type:"java.util.List<java.lang.String>"> = var %1 @"l"; 83 java.enhancedFor 84 ()java.type:"java.util.List<java.lang.String>" -> { 85 %3 : java.type:"java.util.List<java.lang.String>" = var.load %2; 86 %4 : java.type:"java.util.stream.Stream<java.lang.String>" = invoke %3 @java.ref:"java.util.List::stream():java.util.stream.Stream"; 87 %5 : java.type:"java.util.function.Predicate<java.lang.String>" = lambda (%6 : java.type:"java.lang.String")java.type:"boolean" -> { 88 %7 : Var<java.type:"java.lang.String"> = var %6 @"s"; 89 %8 : java.type:"java.lang.String" = var.load %7; 90 %9 : java.type:"int" = invoke %8 @java.ref:"java.lang.String::length():int"; 91 %10 : java.type:"int" = constant @10; 92 %11 : java.type:"boolean" = lt %9 %10; 93 return %11; 94 }; 95 %12 : java.type:"java.util.stream.Stream<java.lang.String>" = invoke %4 %5 @java.ref:"java.util.stream.Stream::filter(java.util.function.Predicate):java.util.stream.Stream"; 96 %13 : java.type:"java.util.List<java.lang.String>" = invoke %12 @java.ref:"java.util.stream.Stream::toList():java.util.List"; 97 yield %13; 98 } 99 (%14 : java.type:"java.lang.String")Var<java.type:"java.lang.String"> -> { 100 %15 : Var<java.type:"java.lang.String"> = var %14 @"s"; 101 yield %15; 102 } 103 (%16 : Var<java.type:"java.lang.String">)java.type:"void" -> { 104 %17 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 105 %18 : java.type:"java.lang.String" = var.load %16; 106 invoke %17 %18 @java.ref:"java.io.PrintStream::println(java.lang.String):void"; 107 java.continue; 108 }; 109 return; 110 }; 111 """) 112 void test2(List<String> l) { 113 for (String s : l.stream().filter(s -> s.length() < 10).toList()) { 114 System.out.println(s); 115 } 116 } 117 118 @CodeReflection 119 @IR(""" 120 func @"test2_1" (%0 : java.type:"ForLoopTest", %1 : java.type:"java.util.List<java.lang.String>")java.type:"void" -> { 121 %2 : Var<java.type:"java.util.List<java.lang.String>"> = var %1 @"l"; 122 java.enhancedFor 123 ()java.type:"java.util.List<java.lang.String>" -> { 124 %3 : java.type:"java.util.List<java.lang.String>" = var.load %2; 125 yield %3; 126 } 127 (%4 : java.type:"java.lang.String")Var<java.type:"java.lang.String"> -> { 128 %5 : Var<java.type:"java.lang.String"> = var %4 @"s"; 129 yield %5; 130 } 131 (%6 : Var<java.type:"java.lang.String">)java.type:"void" -> { 132 java.continue; 133 }; 134 return; 135 }; 136 """) 137 void test2_1(List<String> l) { 138 for (String s : l); 139 } 140 141 @CodeReflection 142 @IR(""" 143 func @"test2_2" (%0 : java.type:"ForLoopTest", %1 : java.type:"java.util.List<java.lang.String>")java.type:"java.lang.String" -> { 144 %2 : Var<java.type:"java.util.List<java.lang.String>"> = var %1 @"l"; 145 java.enhancedFor 146 ()java.type:"java.util.List<java.lang.String>" -> { 147 %3 : java.type:"java.util.List<java.lang.String>" = var.load %2; 148 yield %3; 149 } 150 (%4 : java.type:"java.lang.String")Var<java.type:"java.lang.String"> -> { 151 %5 : Var<java.type:"java.lang.String"> = var %4 @"s"; 152 yield %5; 153 } 154 (%6 : Var<java.type:"java.lang.String">)java.type:"void" -> { 155 %7 : java.type:"java.lang.String" = var.load %6; 156 return %7; 157 }; 158 %8 : java.type:"java.lang.String" = constant @""; 159 return %8; 160 }; 161 """) 162 String test2_2(List<String> l) { 163 for (String s : l) { 164 return s; 165 } 166 return ""; 167 } 168 169 @CodeReflection 170 @IR(""" 171 func @"test3" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 172 java.for 173 ()Var<java.type:"int"> -> { 174 %1 : java.type:"int" = constant @0; 175 %2 : Var<java.type:"int"> = var %1 @"i"; 176 yield %2; 177 } 178 (%3 : Var<java.type:"int">)java.type:"boolean" -> { 179 %4 : java.type:"int" = var.load %3; 180 %5 : java.type:"int" = constant @10; 181 %6 : java.type:"boolean" = lt %4 %5; 182 yield %6; 183 } 184 (%7 : Var<java.type:"int">)java.type:"void" -> { 185 %8 : java.type:"int" = var.load %7; 186 %9 : java.type:"int" = constant @1; 187 %10 : java.type:"int" = add %8 %9; 188 var.store %7 %10; 189 yield; 190 } 191 (%11 : Var<java.type:"int">)java.type:"void" -> { 192 %12 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 193 %13 : java.type:"int" = var.load %11; 194 invoke %12 %13 @java.ref:"java.io.PrintStream::println(int):void"; 195 java.continue; 196 }; 197 return; 198 }; 199 """) 200 void test3() { 201 for (int i = 0; i < 10; i++) { 202 System.out.println(i); 203 } 204 } 205 206 @CodeReflection 207 @IR(""" 208 func @"test3_1" (%0 : java.type:"ForLoopTest")java.type:"int" -> { 209 java.for 210 ()Var<java.type:"int"> -> { 211 %1 : java.type:"int" = constant @0; 212 %2 : Var<java.type:"int"> = var %1 @"i"; 213 yield %2; 214 } 215 (%3 : Var<java.type:"int">)java.type:"boolean" -> { 216 %4 : java.type:"int" = var.load %3; 217 %5 : java.type:"int" = constant @10; 218 %6 : java.type:"boolean" = lt %4 %5; 219 yield %6; 220 } 221 (%7 : Var<java.type:"int">)java.type:"void" -> { 222 %8 : java.type:"int" = var.load %7; 223 %9 : java.type:"int" = constant @1; 224 %10 : java.type:"int" = add %8 %9; 225 var.store %7 %10; 226 yield; 227 } 228 (%11 : Var<java.type:"int">)java.type:"void" -> { 229 %12 : java.type:"int" = var.load %11; 230 return %12; 231 }; 232 %13 : java.type:"int" = constant @-1; 233 return %13; 234 }; 235 """) 236 int test3_1() { 237 for (int i = 0; i < 10; i++) { 238 return i; 239 } 240 return -1; 241 } 242 243 @CodeReflection 244 @IR(""" 245 func @"test4" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 246 java.for 247 ()Var<java.type:"int"> -> { 248 %1 : java.type:"int" = constant @0; 249 %2 : Var<java.type:"int"> = var %1 @"i"; 250 yield %2; 251 } 252 (%3 : Var<java.type:"int">)java.type:"boolean" -> { 253 %4 : java.type:"int" = var.load %3; 254 %5 : java.type:"int" = constant @10; 255 %6 : java.type:"boolean" = lt %4 %5; 256 yield %6; 257 } 258 (%7 : Var<java.type:"int">)java.type:"void" -> { 259 %8 : java.type:"int" = var.load %7; 260 %9 : java.type:"int" = constant @1; 261 %10 : java.type:"int" = add %8 %9; 262 var.store %7 %10; 263 yield; 264 } 265 (%11 : Var<java.type:"int">)java.type:"void" -> { 266 %12 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 267 %13 : java.type:"int" = var.load %11; 268 invoke %12 %13 @java.ref:"java.io.PrintStream::println(int):void"; 269 java.continue; 270 }; 271 return; 272 }; 273 """) 274 void test4() { 275 for (int i = 0; i < 10; i = i + 1) 276 System.out.println(i); 277 } 278 279 @CodeReflection 280 @IR(""" 281 func @"test5" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 282 java.for 283 ()Var<java.type:"int"> -> { 284 %1 : java.type:"int" = constant @0; 285 %2 : Var<java.type:"int"> = var %1 @"i"; 286 yield %2; 287 } 288 (%3 : Var<java.type:"int">)java.type:"boolean" -> { 289 %4 : java.type:"int" = var.load %3; 290 %5 : java.type:"int" = constant @10; 291 %6 : java.type:"boolean" = lt %4 %5; 292 yield %6; 293 } 294 (%7 : Var<java.type:"int">)java.type:"void" -> { 295 %8 : java.type:"int" = var.load %7; 296 %9 : java.type:"int" = constant @1; 297 %10 : java.type:"int" = add %8 %9; 298 var.store %7 %10; 299 yield; 300 } 301 (%11 : Var<java.type:"int">)java.type:"void" -> { 302 java.continue; 303 }; 304 return; 305 }; 306 """) 307 void test5() { 308 for (int i = 0; i < 10; i = i + 1); 309 } 310 311 @CodeReflection 312 @IR(""" 313 func @"test6" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 314 %1 : java.type:"int" = constant @0; 315 %2 : Var<java.type:"int"> = var %1 @"i"; 316 java.for 317 ()java.type:"void" -> { 318 yield; 319 } 320 ()java.type:"boolean" -> { 321 %3 : java.type:"int" = var.load %2; 322 %4 : java.type:"int" = constant @10; 323 %5 : java.type:"boolean" = lt %3 %4; 324 yield %5; 325 } 326 ()java.type:"void" -> { 327 %6 : java.type:"int" = var.load %2; 328 %7 : java.type:"int" = constant @1; 329 %8 : java.type:"int" = add %6 %7; 330 var.store %2 %8; 331 yield; 332 } 333 ()java.type:"void" -> { 334 %9 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 335 %10 : java.type:"int" = var.load %2; 336 invoke %9 %10 @java.ref:"java.io.PrintStream::println(int):void"; 337 java.continue; 338 }; 339 return; 340 }; 341 """) 342 void test6() { 343 int i = 0; 344 for (; i < 10; i = i + 1) { 345 System.out.println(i); 346 } 347 } 348 349 @CodeReflection 350 @IR(""" 351 func @"test7" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 352 %1 : java.type:"int" = constant @0; 353 %2 : Var<java.type:"int"> = var %1 @"i"; 354 java.for 355 ()java.type:"void" -> { 356 %3 : java.type:"int" = var.load %2; 357 %4 : java.type:"int" = constant @1; 358 %5 : java.type:"int" = add %3 %4; 359 var.store %2 %5; 360 yield; 361 } 362 ()java.type:"boolean" -> { 363 %6 : java.type:"int" = var.load %2; 364 %7 : java.type:"int" = constant @10; 365 %8 : java.type:"boolean" = lt %6 %7; 366 yield %8; 367 } 368 ()java.type:"void" -> { 369 %9 : java.type:"int" = var.load %2; 370 %10 : java.type:"int" = constant @1; 371 %11 : java.type:"int" = add %9 %10; 372 var.store %2 %11; 373 yield; 374 } 375 ()java.type:"void" -> { 376 %12 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 377 %13 : java.type:"int" = var.load %2; 378 invoke %12 %13 @java.ref:"java.io.PrintStream::println(int):void"; 379 java.continue; 380 }; 381 return; 382 }; 383 """) 384 void test7() { 385 int i = 0; 386 for (i = i + 1; i < 10; i = i + 1) { 387 System.out.println(i); 388 } 389 } 390 391 @CodeReflection 392 @IR(""" 393 func @"test8" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 394 java.for 395 ()Var<java.type:"int"> -> { 396 %1 : java.type:"int" = constant @0; 397 %2 : Var<java.type:"int"> = var %1 @"i"; 398 yield %2; 399 } 400 (%3 : Var<java.type:"int">)java.type:"boolean" -> { 401 %4 : java.type:"boolean" = constant @true; 402 yield %4; 403 } 404 (%5 : Var<java.type:"int">)java.type:"void" -> { 405 %6 : java.type:"int" = var.load %5; 406 %7 : java.type:"int" = constant @1; 407 %8 : java.type:"int" = add %6 %7; 408 var.store %5 %8; 409 yield; 410 } 411 (%9 : Var<java.type:"int">)java.type:"void" -> { 412 %10 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 413 %11 : java.type:"int" = var.load %9; 414 invoke %10 %11 @java.ref:"java.io.PrintStream::println(int):void"; 415 java.continue; 416 }; 417 unreachable; 418 }; 419 """) 420 void test8() { 421 for (int i = 0; ; i = i + 1) { 422 System.out.println(i); 423 } 424 } 425 426 @CodeReflection 427 @IR(""" 428 func @"test9" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 429 java.for 430 ()Var<java.type:"int"> -> { 431 %1 : java.type:"int" = constant @0; 432 %2 : Var<java.type:"int"> = var %1 @"i"; 433 yield %2; 434 } 435 (%3 : Var<java.type:"int">)java.type:"boolean" -> { 436 %4 : java.type:"boolean" = constant @true; 437 yield %4; 438 } 439 (%5 : Var<java.type:"int">)java.type:"void" -> { 440 yield; 441 } 442 (%6 : Var<java.type:"int">)java.type:"void" -> { 443 %7 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 444 %8 : java.type:"int" = var.load %6; 445 invoke %7 %8 @java.ref:"java.io.PrintStream::println(int):void"; 446 java.continue; 447 }; 448 unreachable; 449 }; 450 """) 451 void test9() { 452 for (int i = 0; ; ) { 453 System.out.println(i); 454 } 455 } 456 457 @CodeReflection 458 @IR(""" 459 func @"test10" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 460 java.for 461 ()java.type:"void" -> { 462 yield; 463 } 464 ()java.type:"boolean" -> { 465 %1 : java.type:"boolean" = constant @true; 466 yield %1; 467 } 468 ()java.type:"void" -> { 469 yield; 470 } 471 ()java.type:"void" -> { 472 java.continue; 473 }; 474 unreachable; 475 }; 476 """) 477 void test10() { 478 for (; ; ) { 479 } 480 } 481 482 @CodeReflection 483 @IR(""" 484 func @"test11" (%0 : java.type:"ForLoopTest")java.type:"void" -> { 485 java.for 486 ()Tuple<Var<java.type:"int">, Var<java.type:"int">> -> { 487 %1 : java.type:"int" = constant @0; 488 %2 : Var<java.type:"int"> = var %1 @"i"; 489 %3 : java.type:"int" = constant @0; 490 %4 : Var<java.type:"int"> = var %3 @"j"; 491 %5 : Tuple<Var<java.type:"int">, Var<java.type:"int">> = tuple %2 %4; 492 yield %5; 493 } 494 (%6 : Var<java.type:"int">, %7 : Var<java.type:"int">)java.type:"boolean" -> { 495 %8 : java.type:"boolean" = java.cand 496 ()java.type:"boolean" -> { 497 %9 : java.type:"int" = var.load %6; 498 %10 : java.type:"int" = constant @10; 499 %11 : java.type:"boolean" = lt %9 %10; 500 yield %11; 501 } 502 ()java.type:"boolean" -> { 503 %12 : java.type:"int" = var.load %7; 504 %13 : java.type:"int" = constant @20; 505 %14 : java.type:"boolean" = lt %12 %13; 506 yield %14; 507 }; 508 yield %8; 509 } 510 (%15 : Var<java.type:"int">, %16 : Var<java.type:"int">)java.type:"void" -> { 511 %17 : java.type:"int" = var.load %15; 512 %18 : java.type:"int" = constant @1; 513 %19 : java.type:"int" = add %17 %18; 514 var.store %15 %19; 515 %20 : java.type:"int" = var.load %16; 516 %21 : java.type:"int" = constant @2; 517 %22 : java.type:"int" = add %20 %21; 518 var.store %16 %22; 519 yield; 520 } 521 (%23 : Var<java.type:"int">, %24 : Var<java.type:"int">)java.type:"void" -> { 522 %25 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 523 %26 : java.type:"int" = var.load %23; 524 invoke %25 %26 @java.ref:"java.io.PrintStream::println(int):void"; 525 %27 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream"; 526 %28 : java.type:"int" = var.load %24; 527 invoke %27 %28 @java.ref:"java.io.PrintStream::println(int):void"; 528 java.continue; 529 }; 530 return; 531 }; 532 """) 533 void test11() { 534 for (int i = 0, j = 0; i < 10 && j < 20; i = i + 1, j = j + 2) { 535 System.out.println(i); 536 System.out.println(j); 537 } 538 } 539 540 @CodeReflection 541 @IR(""" 542 func @"test12" (%0 : java.type:"ForLoopTest", %1 : java.type:"int")java.type:"void" -> { 543 %2 : Var<java.type:"int"> = var %1 @"r"; 544 java.for 545 ()Var<java.type:"int"> -> { 546 %3 : java.type:"int" = constant @0; 547 %4 : Var<java.type:"int"> = var %3 @"i"; 548 yield %4; 549 } 550 (%5 : Var<java.type:"int">)java.type:"boolean" -> { 551 %6 : java.type:"int" = var.load %5; 552 %7 : java.type:"int" = constant @10; 553 %8 : java.type:"boolean" = lt %6 %7; 554 yield %8; 555 } 556 (%9 : Var<java.type:"int">)java.type:"void" -> { 557 %10 : java.type:"int" = var.load %9; 558 %11 : java.type:"int" = constant @1; 559 %12 : java.type:"int" = add %10 %11; 560 var.store %9 %12; 561 yield; 562 } 563 (%13 : Var<java.type:"int">)java.type:"void" -> { 564 java.if 565 ()java.type:"boolean" -> { 566 %14 : java.type:"int" = var.load %2; 567 %15 : java.type:"int" = constant @0; 568 %16 : java.type:"boolean" = eq %14 %15; 569 yield %16; 570 } 571 ()java.type:"void" -> { 572 java.break; 573 } 574 ()java.type:"boolean" -> { 575 %17 : java.type:"int" = var.load %2; 576 %18 : java.type:"int" = constant @1; 577 %19 : java.type:"boolean" = eq %17 %18; 578 yield %19; 579 } 580 ()java.type:"void" -> { 581 java.continue; 582 } 583 ()java.type:"void" -> { 584 yield; 585 }; 586 java.continue; 587 }; 588 return; 589 }; 590 """) 591 void test12(int r) { 592 for (int i = 0; i < 10; i++) { 593 if (r == 0) { 594 break; 595 } else if (r == 1) { 596 continue; 597 } 598 } 599 } 600 601 }