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