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 import org.testng.Assert;
 25 import org.testng.annotations.Test;
 26 
 27 import java.lang.invoke.MethodHandles;
 28 import java.lang.reflect.Method;
 29 import jdk.incubator.code.Op;
 30 import jdk.incubator.code.OpTransformer;
 31 import jdk.incubator.code.analysis.SSA;
 32 import jdk.incubator.code.interpreter.Interpreter;
 33 import jdk.incubator.code.op.CoreOp;
 34 import jdk.incubator.code.op.ExtendedOp;
 35 import jdk.incubator.code.type.CoreTypeFactory;
 36 import jdk.incubator.code.writer.OpBuilder;
 37 import jdk.incubator.code.CodeReflection;
 38 import java.util.Optional;
 39 import java.util.stream.Stream;
 40 
 41 /*
 42  * @test
 43  * @modules jdk.incubator.code
 44  * @run testng TestCodeBuilder
 45  */
 46 
 47 public class TestCodeBuilder {
 48 
 49     @CodeReflection
 50     static void constants() {
 51         boolean bool = false;
 52         byte b = 1;
 53         char c = 'a';
 54         short s = 1;
 55         int i = 1;
 56         long l = 1L;
 57         float f = 1.0f;
 58         double d = 1.0;
 59         String str = "1";
 60         Object obj = null;
 61         Class<?> klass = Object.class;
 62     }
 63 
 64     @Test
 65     public void testConstants() {
 66         testWithTransforms(getFuncOp("constants"));
 67     }
 68 
 69     static record X(int f) {
 70         void m() {}
 71     }
 72 
 73     @CodeReflection
 74     static void reflect() {
 75         X x = new X(1);
 76         int i = x.f;
 77         x.m();
 78         X[] ax = new X[1];
 79         int l = ax.length;
 80         x = ax[0];
 81 
 82         Object o = x;
 83         x = (X) o;
 84         if (o instanceof X) {
 85             return;
 86         }
 87         if (o instanceof X(var a)) {
 88             return;
 89         }
 90     }
 91 
 92     @Test
 93     public void testReflect() {
 94         testWithTransforms(getFuncOp("reflect"));
 95     }
 96 
 97     @CodeReflection
 98     static int bodies(int m, int n) {
 99         int sum = 0;
100         for (int i = 0; i < m; i++) {
101             for (int j = 0; j < n; j++) {
102                 sum += i + j;
103             }
104         }
105         return m > 10 ? sum : 0;
106     }
107 
108     @Test
109     public void testBodies() {
110         testWithTransforms(getFuncOp("bodies"));
111     }
112 
113     public void testWithTransforms(CoreOp.FuncOp f) {
114         test(f);
115 
116         f = f.transform(OpTransformer.LOWERING_TRANSFORMER);
117         test(f);
118 
119         f = SSA.transform(f);
120         test(f);
121     }
122 
123     static void test(CoreOp.FuncOp fExpected) {
124         CoreOp.FuncOp fb = OpBuilder.createBuilderFunction(fExpected);
125         CoreOp.FuncOp fActual = (CoreOp.FuncOp) Interpreter.invoke(MethodHandles.lookup(),
126                 fb, ExtendedOp.FACTORY, CoreTypeFactory.CORE_TYPE_FACTORY);
127         Assert.assertEquals(fActual.toText(), fExpected.toText());
128     }
129 
130     static CoreOp.FuncOp getFuncOp(String name) {
131         Optional<Method> om = Stream.of(TestCodeBuilder.class.getDeclaredMethods())
132                 .filter(m -> m.getName().equals(name))
133                 .findFirst();
134 
135         Method m = om.get();
136         return Op.ofMethod(m).get();
137     }
138 }