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 }