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 captured values in quoted lambdas. 27 * @modules jdk.incubator.code 28 * @run junit TestCaptureQuoted 29 */ 30 31 import jdk.incubator.code.dialect.core.CoreOp.Var; 32 import jdk.incubator.code.Op; 33 import jdk.incubator.code.Quoted; 34 import jdk.incubator.code.interpreter.Interpreter; 35 import org.junit.jupiter.api.Test; 36 import org.junit.jupiter.params.ParameterizedTest; 37 import org.junit.jupiter.params.provider.MethodSource; 38 39 import java.lang.invoke.MethodHandles; 40 import java.util.ArrayList; 41 import java.util.Iterator; 42 import java.util.List; 43 import java.util.stream.IntStream; 44 45 import static org.junit.jupiter.api.Assertions.assertEquals; 46 47 48 public class TestCaptureQuoted { 49 50 @ParameterizedTest 51 @MethodSource("ints") 52 public void testCaptureIntParam(int x) { 53 Quoted quoted = (int y) -> x + y; 54 assertEquals(1, quoted.capturedValues().size()); 55 assertEquals(x, ((Var)quoted.capturedValues().values().iterator().next()).value()); 56 List<Object> arguments = new ArrayList<>(); 57 arguments.add(1); 58 arguments.addAll(quoted.capturedValues().values()); 59 int res = (int)Interpreter.invoke(MethodHandles.lookup(), (Op & Op.Invokable) quoted.op(), 60 arguments); 61 assertEquals(x + 1, res); 62 } 63 64 static class Context { 65 final int x; 66 67 Context(int x) { 68 this.x = x; 69 } 70 71 Quoted quoted() { 72 return (int y) -> x + y; 73 } 74 } 75 76 @ParameterizedTest 77 @MethodSource("ints") 78 public void testCaptureIntField(int x) { 79 Context context = new Context(x); 80 Quoted quoted = context.quoted(); 81 assertEquals(1, quoted.capturedValues().size()); 82 assertEquals(context, quoted.capturedValues().values().iterator().next()); 83 List<Object> arguments = new ArrayList<>(); 84 arguments.add(1); 85 arguments.addAll(quoted.capturedValues().values()); 86 int res = (int)Interpreter.invoke(MethodHandles.lookup(), (Op & Op.Invokable) quoted.op(), 87 arguments); 88 assertEquals(x + 1, res); 89 } 90 91 @Test 92 public void testCaptureThisRefAndIntConstant() { 93 final int x = 100; 94 String hello = "hello"; 95 Quoted quoted = (Integer y) -> y.intValue() + hashCode() + hello.length() + x; 96 assertEquals(3, quoted.capturedValues().size()); 97 Iterator<Object> it = quoted.capturedValues().values().iterator(); 98 assertEquals(this, it.next()); 99 assertEquals(hello, ((Var)it.next()).value()); 100 assertEquals(x, ((Var)it.next()).value()); 101 List<Object> arguments = new ArrayList<>(); 102 arguments.add(1); 103 arguments.addAll(quoted.capturedValues().values()); 104 int res = (int)Interpreter.invoke(MethodHandles.lookup(), (Op & Op.Invokable) quoted.op(), 105 arguments); 106 assertEquals(x + 1 + hashCode() + hello.length(), res); 107 } 108 109 @Test 110 public void testCaptureThisInInvocationArg() { 111 Quoted quoted = (Number y) -> y.intValue() + Integer.valueOf(hashCode()); 112 assertEquals(1, quoted.capturedValues().size()); 113 Iterator<Object> it = quoted.capturedValues().values().iterator(); 114 assertEquals(this, it.next()); 115 List<Object> arguments = new ArrayList<>(); 116 arguments.add(1); 117 arguments.addAll(quoted.capturedValues().values()); 118 int res = (int)Interpreter.invoke(MethodHandles.lookup(), (Op & Op.Invokable) quoted.op(), 119 arguments); 120 assertEquals(1 + hashCode(), res); 121 } 122 123 record R(int i) {} 124 125 @Test 126 public void testCaptureThisInNewArg() { 127 Quoted quoted = (Number y) -> y.intValue() + new R(hashCode()).i; 128 assertEquals(1, quoted.capturedValues().size()); 129 Iterator<Object> it = quoted.capturedValues().values().iterator(); 130 assertEquals(this, it.next()); 131 List<Object> arguments = new ArrayList<>(); 132 arguments.add(1); 133 arguments.addAll(quoted.capturedValues().values()); 134 int res = (int)Interpreter.invoke(MethodHandles.lookup(), (Op & Op.Invokable) quoted.op(), 135 arguments); 136 assertEquals(1 + hashCode(), res); 137 } 138 139 140 public static IntStream ints() { 141 return IntStream.range(0, 50); 142 } 143 }