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 * @modules jdk.incubator.code
27 * @run junit TestModuleOp
28 * @run junit/othervm -Dbabylon.ssa=cytron TestModuleOp
29 */
30
31 import jdk.incubator.code.Block;
32 import jdk.incubator.code.Op;
33 import jdk.incubator.code.Reflect;
34 import jdk.incubator.code.analysis.SSA;
35 import jdk.incubator.code.dialect.core.CoreOp;
36 import jdk.incubator.code.dialect.core.CoreType;
37 import jdk.incubator.code.dialect.java.JavaOp;
38 import jdk.incubator.code.dialect.java.MethodRef;
39 import org.junit.jupiter.api.Assertions;
40 import org.junit.jupiter.api.Test;
41
42 import java.lang.invoke.MethodHandles;
43 import java.lang.reflect.Method;
44 import java.util.*;
45 import java.util.function.Consumer;
46 import java.util.function.IntUnaryOperator;
47 import java.util.stream.Stream;
48
49 import static jdk.incubator.code.dialect.core.CoreOp.*;
50 import static jdk.incubator.code.dialect.java.JavaOp.*;
51 import static jdk.incubator.code.dialect.java.JavaType.*;
52
53 public class TestModuleOp {
54
55 @Reflect
56 public static void a() {
57 }
58
59 @Reflect
60 public static int b(int i) {
61 return i;
62 }
63
64 @Reflect
65 public static int c(int i) {
66 return (i * 2) % 5;
67 }
68
69 @Reflect
70 public static int d(int i, int j) {
71 return (c(i) / 4) + j;
72 }
73
74 @Reflect
75 public static int e(int i) {if (i == 0) return i; return e(--i);}
76
77 @Test
78 public void testEmptyLambda() {
79 Runnable runnable = (@Reflect Runnable) () -> {};
80 LambdaOp lambdaOp = (LambdaOp) Op.ofQuotable(runnable).get().op();
81 ModuleOp moduleOp = ModuleOp.ofLambdaOp(lambdaOp, MethodHandles.lookup(), "rootLambda");
82 Assertions.assertTrue(moduleOp.functionTable().keySet().stream().toList().equals(List.of("rootLambda_0")));
83 Assertions.assertTrue(moduleOp.functionTable().get("rootLambda_0").elements().allMatch(e -> e instanceof ReturnOp || e instanceof FuncOp || !(e instanceof Op)));
84 }
85
86 @Test
87 public void testSingleInvoke() {
88 Runnable runnable = (@Reflect Runnable) () -> a();
89 LambdaOp lambdaOp = (LambdaOp) Op.ofQuotable(runnable).get().op();
90 ModuleOp moduleOp = ModuleOp.ofLambdaOp(lambdaOp, MethodHandles.lookup(), "rootLambda");
91 Assertions.assertTrue(moduleOp.functionTable().keySet().stream().toList().equals(List.of("a_0")));
92 }
93
94 @Test
95 public void testMultipleCapture() {
96 int i = 0;
97 int j = 0;
98 Runnable runnable = (@Reflect Runnable) () -> d(i, j);
99 LambdaOp lambdaOp = (LambdaOp) Op.ofQuotable(runnable).get().op();
100 ModuleOp moduleOp = ModuleOp.ofLambdaOp(lambdaOp, MethodHandles.lookup(), "rootLambda");
101 Assertions.assertTrue(moduleOp.functionTable().keySet().stream().toList().equals(List.of("d_0", "c_1")));
102 }
103
104 @Test
105 public void testArray() throws NoSuchMethodException {
106 int i = 10;
107 int[] array = new int[i];
108 Consumer<Integer> lambda = (@Reflect Consumer<Integer>) (j) -> c(b(i) + array[j]);
109 LambdaOp lambdaOp = (LambdaOp) Op.ofQuotable(lambda).get().op();
110 ModuleOp moduleOp = ModuleOp.ofLambdaOp(lambdaOp, MethodHandles.lookup(), "rootLambda");
111 Assertions.assertTrue(moduleOp.functionTable().keySet().stream().toList().equals(List.of("rootLambda_0", "b_1", "c_2")));
112 }
113
114 @Test
115 public void testTernary() throws NoSuchMethodException {
116 int i = 0;
117 int j = 0;
118 Consumer<Integer> lambda = (@Reflect Consumer<Integer>) (k) -> c(i > k ? b(i) : c(d(j, k)));
119 LambdaOp lambdaOp = (LambdaOp) Op.ofQuotable(lambda).get().op();
120 ModuleOp moduleOp = ModuleOp.ofLambdaOp(lambdaOp, MethodHandles.lookup(), "rootLambda");
121 Assertions.assertTrue(moduleOp.functionTable().keySet().stream().toList().equals(List.of("rootLambda_0", "b_1", "d_2", "c_3")));
122 }
123
124 @Test
125 public void testRepeatLambdaName() {
126 @Reflect IntUnaryOperator runnable = (@Reflect IntUnaryOperator) (int j) -> {return b(1);};
127 LambdaOp lambdaOp = (LambdaOp) Op.ofQuotable(runnable).get().op();
128 ModuleOp moduleOp = ModuleOp.ofLambdaOp(lambdaOp, MethodHandles.lookup(), "b");
129 Assertions.assertTrue(moduleOp.functionTable().keySet().stream().toList().equals(List.of("b_0", "b_1")));
130 }
131
132 @Test
133 public void testMultipleStatements() throws NoSuchMethodException {
134 int i = 0;
135 int j = 0;
136 Consumer<Integer> lambda = (@Reflect Consumer<Integer>) (k) -> {
137 int temp = c(i);
138 a();
139 b(k * d(temp, j));
140 };
141 LambdaOp lambdaOp = (LambdaOp) Op.ofQuotable(lambda).get().op();
142 ModuleOp moduleOp = ModuleOp.ofLambdaOp(lambdaOp, MethodHandles.lookup(), "rootLambda");
143 Assertions.assertTrue(moduleOp.functionTable().keySet().stream().toList().equals(List.of("rootLambda_0", "c_1", "a_2", "d_3", "b_4")));
144 }
145
146 @Test
147 public void testRecursion() throws ReflectiveOperationException {
148 Runnable runnable = (@Reflect Runnable) () -> e(1);
149 LambdaOp lambdaOp = (LambdaOp) Op.ofQuotable(runnable).get().op();
150 ModuleOp moduleOp = ModuleOp.ofLambdaOp(lambdaOp, MethodHandles.lookup(), "e");
151 Assertions.assertTrue(moduleOp.functionTable().keySet().stream().toList().equals(List.of("e_0", "e_1")));
152 }
153 }