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 java.lang.runtime.CodeReflection;
 25 import java.util.List;
 26 import java.util.function.Consumer;
 27 
 28 /*
 29  * @test
 30  * @summary Smoke test for code reflection with blocks.
 31  * @build BlockTest
 32  * @build CodeReflectionTester
 33  * @run main CodeReflectionTester BlockTest
 34  */
 35 
 36 public class BlockTest {
 37     @CodeReflection
 38     @IR("""
 39             func @"test1" (%0 : BlockTest)void -> {
 40                 java.block ()void -> {
 41                     %1 : int = constant @"0";
 42                     %2 : Var<int> = var %1 @"i";
 43                     yield;
 44                 };
 45                 java.block ()void -> {
 46                     %3 : int = constant @"1";
 47                     %4 : Var<int> = var %3 @"i";
 48                     java.block ()void -> {
 49                         %5 : int = constant @"2";
 50                         %6 : Var<int> = var %5 @"j";
 51                         yield;
 52                     };
 53                     yield;
 54                 };
 55                 return;
 56             };
 57             """)
 58     void test1() {
 59         {
 60             int i = 0;
 61         }
 62 
 63         {
 64             int i = 1;
 65 
 66             {
 67                 int j = 2;
 68             }
 69         }
 70     }
 71 
 72     @CodeReflection
 73     @IR("""
 74             func @"test2" (%0 : BlockTest, %1 : int)void -> {
 75                 %2 : Var<int> = var %1 @"i";
 76                 java.if
 77                     ()boolean -> {
 78                         %3 : int = var.load %2;
 79                         %4 : int = constant @"1";
 80                         %5 : boolean = lt %3 %4;
 81                         yield %5;
 82                     }
 83                     ^then()void -> {
 84                         java.block ()void -> {
 85                             %6 : int = var.load %2;
 86                             %7 : int = constant @"1";
 87                             %8 : int = add %6 %7;
 88                             var.store %2 %8;
 89                             yield;
 90                         };
 91                         yield;
 92                     }
 93                     ^else_if()boolean -> {
 94                         %9 : int = var.load %2;
 95                         %10 : int = constant @"2";
 96                         %11 : boolean = lt %9 %10;
 97                         yield %11;
 98                     }
 99                     ^then()void -> {
100                         java.block ()void -> {
101                             %12 : int = var.load %2;
102                             %13 : int = constant @"2";
103                             %14 : int = add %12 %13;
104                             var.store %2 %14;
105                             yield;
106                         };
107                         yield;
108                     }
109                     ^else()void -> {
110                         java.block ()void -> {
111                             %15 : int = var.load %2;
112                             %16 : int = constant @"3";
113                             %17 : int = add %15 %16;
114                             var.store %2 %17;
115                             yield;
116                         };
117                         yield;
118                     };
119                 return;
120             };
121             """)
122     void test2(int i) {
123         if (i < 1) {
124             {
125                 i += 1;
126             }
127         } else if (i < 2) {
128             {
129                 i += 2;
130             }
131         } else {
132             {
133                 i += 3;
134             }
135         }
136     }
137 
138     @CodeReflection
139     @IR("""
140             func @"test3" (%0 : BlockTest)void -> {
141                 java.for
142                     ^init()void -> {
143                         yield;
144                     }
145                     ^cond()boolean -> {
146                         %1 : boolean = constant @"true";
147                         yield %1;
148                     }
149                     ^update()void -> {
150                         yield;
151                     }
152                     ^body()void -> {
153                         java.block ()void -> {
154                             %2 : int = constant @"0";
155                             %3 : Var<int> = var %2 @"i";
156                             yield;
157                         };
158                         java.continue;
159                     };
160                 return;
161             };
162             """)
163     void test3() {
164         for (;;) {
165             {
166                 int i = 0;
167             }
168         }
169     }
170 
171     @CodeReflection
172     @IR("""
173             func @"test4" (%0 : BlockTest, %1 : int[])void -> {
174                 %2 : Var<int[]> = var %1 @"ia";
175                 java.enhancedFor
176                     ^expr()int[] -> {
177                         %3 : int[] = var.load %2;
178                         yield %3;
179                     }
180                     ^def(%4 : int)Var<int> -> {
181                         %5 : Var<int> = var %4 @"i";
182                         yield %5;
183                     }
184                     ^body(%6 : Var<int>)void -> {
185                         java.block ()void -> {
186                             %7 : int = var.load %6;
187                             %8 : int = constant @"1";
188                             %9 : int = add %7 %8;
189                             var.store %6 %9;
190                             yield;
191                         };
192                         java.continue;
193                     };
194                 return;
195             };
196             """)
197     void test4(int[] ia) {
198         for (int i : ia) {
199             {
200                 i++;
201             }
202         }
203    }
204 
205     @CodeReflection
206     @IR("""
207             func @"test5" (%0 : BlockTest)void -> {
208                 %1 : java.util.function.Consumer<java.lang.String> = lambda (%2 : java.lang.String)void -> {
209                     %3 : Var<java.lang.String> = var %2 @"s";
210                     java.block ()void -> {
211                         %4 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream";
212                         %5 : java.lang.String = var.load %3;
213                         invoke %4 %5 @"java.io.PrintStream::println(java.lang.String)void";
214                         yield;
215                     };
216                     return;
217                 };
218                 %6 : Var<java.util.function.Consumer<java.lang.String>> = var %1 @"c";
219                 return;
220             };
221             """)
222    void test5() {
223         Consumer<String> c = s -> {
224             {
225                 System.out.println(s);
226             }
227         };
228     }
229 
230 
231     @CodeReflection
232     @IR("""
233             func @"test6" (%0 : BlockTest)void -> {
234                  java.if
235                      ()boolean -> {
236                          %1 : boolean = constant @"true";
237                          yield %1;
238                      }
239                      ^then()void -> {
240                          java.block ()void -> {
241                              return;
242                          };
243                          yield;
244                      }
245                      ^else()void -> {
246                          yield;
247                      };
248                  java.if
249                      ()boolean -> {
250                          %2 : boolean = constant @"true";
251                          yield %2;
252                      }
253                      ^then()void -> {
254                          java.block ()void -> {
255                              %3 : java.lang.RuntimeException = new @"func<java.lang.RuntimeException>";
256                              throw %3;
257                          };
258                          yield;
259                      }
260                      ^else()void -> {
261                          yield;
262                      };
263                  return;
264              };
265              """)
266     void test6() {
267         if (true) {
268             {
269                 return;
270             }
271         }
272 
273         if (true) {
274             {
275                 throw new RuntimeException();
276             }
277         }
278     }
279 }