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 quotable lambdas. 27 * @build QuotableIntersectionTest 28 * @build CodeReflectionTester 29 * @run main CodeReflectionTester QuotableIntersectionTest 30 */ 31 32 import java.lang.reflect.code.Quotable; 33 import java.lang.runtime.CodeReflection; 34 import java.util.function.IntBinaryOperator; 35 import java.util.function.IntFunction; 36 import java.util.function.IntSupplier; 37 import java.util.function.IntUnaryOperator; 38 39 public class QuotableIntersectionTest { 40 @IR(""" 41 func @"f" ()void -> { 42 %0 : java.lang.reflect.code.Quotable = lambda ()void -> { 43 return; 44 }; 45 return; 46 }; 47 """) 48 static final Quotable QUOTED_NO_PARAM_VOID = (Quotable & Runnable) () -> { 49 }; 50 51 @IR(""" 52 func @"f" ()void -> { 53 %0 : java.lang.reflect.code.Quotable = lambda ()int -> { 54 %2 : int = constant @"1"; 55 return %2; 56 }; 57 return; 58 }; 59 """) 60 static final Quotable QUOTED_NO_PARAM_CONST = (Quotable & IntSupplier) () -> 1; 61 62 @IR(""" 63 func @"f" ()void -> { 64 %0 : java.lang.reflect.code.Quotable = lambda (%1 : int)int -> { 65 %2 : Var<int> = var %1 @"x"; 66 %3 : int = var.load %2; 67 return %3; 68 }; 69 return; 70 }; 71 """) 72 static final Quotable QUOTED_ID = (Quotable & IntUnaryOperator) x -> x; 73 74 @IR(""" 75 func @"f" ()void -> { 76 %0 : java.lang.reflect.code.Quotable = lambda (%1 : int, %2 : int)int -> { 77 %3 : Var<int> = var %1 @"x"; 78 %4 : Var<int> = var %2 @"y"; 79 %5 : int = var.load %3; 80 %6 : int = var.load %4; 81 %7 : int = add %5 %6; 82 return %7; 83 }; 84 return; 85 }; 86 """) 87 static final Quotable QUOTED_PLUS = (Quotable & IntBinaryOperator) (x, y) -> x + y; 88 89 @IR(""" 90 func @"f" ()void -> { 91 %0 : java.lang.reflect.code.Quotable = lambda ()void -> { 92 %1 : java.lang.AssertionError = new @"func<java.lang.AssertionError>"; 93 throw %1; 94 }; 95 return; 96 }; 97 """) 98 static final Quotable QUOTED_THROW_NO_PARAM = (Quotable & Runnable) () -> { 99 throw new AssertionError(); 100 }; 101 102 @IR(""" 103 func @"f" (%1 : Var<int>)void -> { 104 %2 : java.lang.reflect.code.Quotable = lambda (%4 : int)int -> { 105 %5 : Var<int> = var %4 @"y"; 106 %6 : int = var.load %1; 107 %7 : int = var.load %5; 108 %8 : int = add %6 %7; 109 return %8; 110 }; 111 return; 112 }; 113 """) 114 static final Quotable QUOTED_CAPTURE_PARAM = new Object() { 115 Quotable captureContext(int x) { 116 return (Quotable & IntUnaryOperator) y -> x + y; 117 } 118 }.captureContext(42); 119 120 static class Context { 121 int x, y; 122 123 Quotable capture() { 124 return (Quotable & IntUnaryOperator) z -> x + y + z; 125 } 126 } 127 128 @IR(""" 129 func @"f" (%0 : QuotableIntersectionTest$Context)void -> { 130 %1 : java.lang.reflect.code.Quotable = lambda (%3 : int)int -> { 131 %4 : Var<int> = var %3 @"z"; 132 %5 : int = field.load %0 @"QuotableIntersectionTest$Context::x()int"; 133 %6 : int = field.load %0 @"QuotableIntersectionTest$Context::y()int"; 134 %7 : int = add %5 %6; 135 %8 : int = var.load %4; 136 %9 : int = add %7 %8; 137 return %9; 138 }; 139 return; 140 }; 141 """) 142 static final Quotable QUOTED_CAPTURE_FIELD = new Context().capture(); 143 144 @CodeReflection 145 @IR(""" 146 func @"captureParam" (%0 : int)void -> { 147 %1 : Var<int> = var %0 @"x"; 148 %2 : java.util.function.IntUnaryOperator = lambda (%3 : int)int -> { 149 %4 : Var<int> = var %3 @"y"; 150 %5 : int = var.load %1; 151 %6 : int = var.load %4; 152 %7 : int = add %5 %6; 153 return %7; 154 }; 155 %8 : Var<java.util.function.IntUnaryOperator> = var %2 @"op"; 156 return; 157 }; 158 """) 159 static void captureParam(int x) { 160 IntUnaryOperator op = (IntUnaryOperator & Quotable) y -> x + y; 161 } 162 163 int x, y; 164 165 @CodeReflection 166 @IR(""" 167 func @"captureField" (%0 : QuotableIntersectionTest)void -> { 168 %1 : java.util.function.IntUnaryOperator = lambda (%2 : int)int -> { 169 %3 : Var<int> = var %2 @"z"; 170 %4 : int = field.load %0 @"QuotableIntersectionTest::x()int"; 171 %5 : int = field.load %0 @"QuotableIntersectionTest::y()int"; 172 %6 : int = add %4 %5; 173 %7 : int = var.load %3; 174 %8 : int = add %6 %7; 175 return %8; 176 }; 177 %9 : Var<java.util.function.IntUnaryOperator> = var %1 @"op"; 178 return; 179 }; 180 """) 181 void captureField() { 182 IntUnaryOperator op = (IntUnaryOperator & Quotable) z -> x + y + z; 183 } 184 185 static void m() { 186 } 187 188 @IR(""" 189 func @"f" ()void -> { 190 %0 : java.lang.reflect.code.Quotable = lambda ()void -> { 191 invoke @"QuotableIntersectionTest::m()void"; 192 return; 193 }; 194 return; 195 }; 196 """) 197 static final Quotable QUOTED_NO_PARAM_VOID_REF = (Quotable & Runnable) QuotableIntersectionTest::m; 198 199 static int g(int i) { 200 return i; 201 } 202 203 @IR(""" 204 func @"f" ()void -> { 205 %0 : java.lang.reflect.code.Quotable = lambda (%1 : int)int -> { 206 %2 : Var<int> = var %1 @"x$0"; 207 %3 : int = var.load %2; 208 %4 : int = invoke %3 @"QuotableIntersectionTest::g(int)int"; 209 return %4; 210 }; 211 return; 212 }; 213 """) 214 static final Quotable QUOTED_INT_PARAM_INT_RET_REF = (Quotable & IntUnaryOperator) QuotableIntersectionTest::g; 215 216 @IR(""" 217 func @"f" ()void -> { 218 %0 : java.lang.reflect.code.Quotable = lambda (%1 : int)int[] -> { 219 %2 : Var<int> = var %1 @"x$0"; 220 %3 : int = var.load %2; 221 %4 : int[] = new %3 @"func<int[], int>"; 222 return %4; 223 }; 224 return; 225 }; 226 """) 227 static final Quotable QUOTED_INT_PARAM_ARR_RET_REF = (Quotable & IntFunction<int[]>) int[]::new; 228 229 static class ContextRef { 230 int g(int i) { 231 return i; 232 } 233 234 Quotable capture() { 235 return (Quotable & IntUnaryOperator) this::g; 236 } 237 } 238 239 @IR(""" 240 func @"f" (%0 : QuotableIntersectionTest$ContextRef)void -> { 241 %1 : java.lang.reflect.code.Quotable = lambda (%3 : int)int -> { 242 %4 : Var<int> = var %3 @"x$0"; 243 %5 : int = var.load %4; 244 %6 : int = invoke %0 %5 @"QuotableIntersectionTest$ContextRef::g(int)int"; 245 return %6; 246 }; 247 return; 248 }; 249 """) 250 static final Quotable QUOTED_CAPTURE_THIS_REF = new ContextRef().capture(); 251 }