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 * @summary Smoke test for code reflection with quoted lambdas.
27 * @modules jdk.incubator.code
28 * @build QuotedTest
29 * @build CodeReflectionTester
30 * @run main CodeReflectionTester QuotedTest
31 */
32
33 import jdk.incubator.code.Quoted;
34 import jdk.incubator.code.CodeReflection;
35
36 import java.util.List;
37
38 public class QuotedTest {
39 @IR("""
40 func @"f" ()java.type:"void" -> {
41 %0 : func<java.type:"void"> = closure ()java.type:"void" -> {
42 return;
43 };
44 return;
45 };
46 """)
47 static final Quoted QUOTED_NO_PARAM_VOID = () -> {
48 };
49
50 @IR("""
51 func @"f" ()java.type:"void" -> {
52 %0 : func<java.type:"int"> = closure ()java.type:"int" -> {
53 %1 : java.type:"int" = constant @1;
54 return %1;
55 };
56 return;
57 };
58 """)
59 static final Quoted QUOTED_NO_PARAM_CONST = () -> 1;
60
61 @IR("""
62 func @"f" ()java.type:"void" -> {
63 %0 : func<java.type:"int", java.type:"int"> = closure (%1 : java.type:"int")java.type:"int" -> {
64 %2 : Var<java.type:"int"> = var %1 @"x";
65 %3 : java.type:"int" = var.load %2;
66 return %3;
67 };
68 return;
69 };
70 """)
71 static final Quoted QUOTED_ID = (int x) -> x;
72
73 @IR("""
74 func @"f" ()java.type:"void" -> {
75 %0 : func<java.type:"int", java.type:"int", java.type:"int"> = closure (%1 : java.type:"int", %2 : java.type:"int")java.type:"int" -> {
76 %3 : Var<java.type:"int"> = var %1 @"x";
77 %4 : Var<java.type:"int"> = var %2 @"y";
78 %5 : java.type:"int" = var.load %3;
79 %6 : java.type:"int" = var.load %4;
80 %7 : java.type:"int" = add %5 %6;
81 return %7;
82 };
83 return;
84 };
85 """)
86 static final Quoted QUOTED_PLUS = (int x, int y) -> x + y;
87
88 @IR("""
89 func @"f" ()java.type:"void" -> {
90 %0 : func<java.type:"java.lang.Object"> = closure ()java.type:"java.lang.Object" -> {
91 %1 : java.type:"java.lang.AssertionError" = new @java.ref:"java.lang.AssertionError::()";
92 throw %1;
93 };
94 return;
95 };
96 """)
97 static final Quoted QUOTED_THROW_NO_PARAM = () -> {
98 throw new AssertionError();
99 };
100
101 // can we write out the root op then extract the closure ?
102
103 @IR("""
104 func @"f" (%0 : Var<java.type:"int">)java.type:"void" -> {
105 %1 : func<java.type:"int", java.type:"int"> = closure (%2 : java.type:"int")java.type:"int" -> {
106 %3 : Var<java.type:"int"> = var %2 @"y";
107 %4 : java.type:"int" = var.load %0;
108 %5 : java.type:"int" = var.load %3;
109 %6 : java.type:"int" = add %4 %5;
110 return %6;
111 };
112 return;
113 };
114 """)
115 static final Quoted QUOTED_CAPTURE_PARAM = new Object() {
116 Quoted captureContext(int x) {
117 return (int y) -> x + y;
118 }
119 }.captureContext(42);
120
121 static class Context {
122 int x, y;
123
124 Quoted capture() {
125 return (int z) -> x + y + z;
126 }
127 }
128
129 @IR("""
130 func @"f" (%0 : java.type:"QuotedTest$Context")java.type:"void" -> {
131 %1 : func<java.type:"int", java.type:"int"> = closure (%2 : java.type:"int")java.type:"int" -> {
132 %3 : Var<java.type:"int"> = var %2 @"z";
133 %4 : java.type:"int" = field.load %0 @java.ref:"QuotedTest$Context::x:int";
134 %5 : java.type:"int" = field.load %0 @java.ref:"QuotedTest$Context::y:int";
135 %6 : java.type:"int" = add %4 %5;
136 %7 : java.type:"int" = var.load %3;
137 %8 : java.type:"int" = add %6 %7;
138 return %8;
139 };
140 return;
141 };
142 """)
143 static final Quoted QUOTED_CAPTURE_FIELD = new Context().capture();
144
145 @CodeReflection
146 @IR("""
147 func @"captureParam" (%0 : java.type:"int")java.type:"void" -> {
148 %1 : Var<java.type:"int"> = var %0 @"x";
149 %2 : java.type:"jdk.incubator.code.Quoted" = quoted ()java.type:"void" -> {
150 %3 : func<java.type:"int", java.type:"int"> = closure (%4 : java.type:"int")java.type:"int" -> {
151 %5 : Var<java.type:"int"> = var %4 @"y";
152 %6 : java.type:"int" = var.load %1;
153 %7 : java.type:"int" = var.load %5;
154 %8 : java.type:"int" = add %6 %7;
155 return %8;
156 };
157 yield %3;
158 };
159 %9 : Var<java.type:"jdk.incubator.code.Quoted"> = var %2 @"op";
160 return;
161 };
162 """)
163 static void captureParam(int x) {
164 Quoted op = (int y) -> x + y;
165 }
166
167 int x, y;
168
169 @CodeReflection
170 @IR("""
171 func @"captureField" (%0 : java.type:"QuotedTest")java.type:"void" -> {
172 %1 : java.type:"jdk.incubator.code.Quoted" = quoted ()java.type:"void" -> {
173 %2 : func<java.type:"int", java.type:"int"> = closure (%3 : java.type:"int")java.type:"int" -> {
174 %4 : Var<java.type:"int"> = var %3 @"z";
175 %5 : java.type:"int" = field.load %0 @java.ref:"QuotedTest::x:int";
176 %6 : java.type:"int" = field.load %0 @java.ref:"QuotedTest::y:int";
177 %7 : java.type:"int" = add %5 %6;
178 %8 : java.type:"int" = var.load %4;
179 %9 : java.type:"int" = add %7 %8;
180 return %9;
181 };
182 yield %2;
183 };
184 %10 : Var<java.type:"jdk.incubator.code.Quoted"> = var %1 @"op";
185 return;
186 };
187 """)
188 void captureField() {
189 Quoted op = (int z) -> x + y + z;
190 }
191
192 @CodeReflection
193 @IR("""
194 func @"upwardNonDenotableReturn" (%0 : java.type:"QuotedTest")java.type:"void" -> {
195 %1 : java.type:"jdk.incubator.code.Quoted" = quoted ()java.type:"void" -> {
196 %2 : func<java.type:"java.util.List<? extends java.io.Serializable>", java.type:"boolean", java.type:"java.util.List<java.lang.String>", java.type:"java.util.List<java.lang.Integer>"> = closure (%3 : java.type:"boolean", %4 : java.type:"java.util.List<java.lang.String>", %5 : java.type:"java.util.List<java.lang.Integer>")java.type:"java.util.List<? extends java.io.Serializable>" -> {
197 %6 : Var<java.type:"boolean"> = var %3 @"cond";
198 %7 : Var<java.type:"java.util.List<java.lang.String>"> = var %4 @"ls";
199 %8 : Var<java.type:"java.util.List<java.lang.Integer>"> = var %5 @"li";
200 %9 : java.type:"java.util.List<? extends java.io.Serializable>" = java.cexpression
201 ()java.type:"boolean" -> {
202 %10 : java.type:"boolean" = var.load %6;
203 yield %10;
204 }
205 ()java.type:"java.util.List<? extends java.io.Serializable>" -> {
206 %11 : java.type:"java.util.List<java.lang.String>" = var.load %7;
207 yield %11;
208 }
209 ()java.type:"java.util.List<? extends java.io.Serializable>" -> {
210 %12 : java.type:"java.util.List<java.lang.Integer>" = var.load %8;
211 yield %12;
212 };
213 return %9;
214 };
215 yield %2;
216 };
217 %13 : Var<java.type:"jdk.incubator.code.Quoted"> = var %1 @"op";
218 return;
219 };
220 """)
221 void upwardNonDenotableReturn() {
222 Quoted op = (boolean cond, List<String> ls, List<Integer> li) -> cond ? ls : li;
223 }
224 }