| /* |
| * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package jdk.test.lib.jittester.utils; |
| |
| import java.util.Arrays; |
| import java.util.ArrayList; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import jdk.test.lib.jittester.BinaryOperator; |
| import jdk.test.lib.jittester.Block; |
| import jdk.test.lib.jittester.CatchBlock; |
| import jdk.test.lib.jittester.IRNode; |
| import jdk.test.lib.jittester.Literal; |
| import jdk.test.lib.jittester.LocalVariable; |
| import jdk.test.lib.jittester.NonStaticMemberVariable; |
| import jdk.test.lib.jittester.Nothing; |
| import jdk.test.lib.jittester.Operator; |
| import jdk.test.lib.jittester.OperatorKind; |
| import jdk.test.lib.jittester.PrintVariables; |
| import jdk.test.lib.jittester.Statement; |
| import jdk.test.lib.jittester.StaticMemberVariable; |
| import jdk.test.lib.jittester.Symbol; |
| import jdk.test.lib.jittester.TryCatchBlock; |
| import jdk.test.lib.jittester.Type; |
| import jdk.test.lib.jittester.TypeList; |
| import jdk.test.lib.jittester.VariableInfo; |
| import jdk.test.lib.jittester.VariableInitialization; |
| import jdk.test.lib.jittester.functions.ArgumentDeclaration; |
| import jdk.test.lib.jittester.functions.Function; |
| import jdk.test.lib.jittester.functions.FunctionDefinition; |
| import jdk.test.lib.jittester.functions.FunctionInfo; |
| import jdk.test.lib.jittester.functions.Return; |
| import jdk.test.lib.jittester.jtreg.Printer; |
| import jdk.test.lib.jittester.loops.CounterInitializer; |
| import jdk.test.lib.jittester.loops.CounterManipulator; |
| import jdk.test.lib.jittester.loops.For; |
| import jdk.test.lib.jittester.loops.Loop; |
| import jdk.test.lib.jittester.loops.LoopingCondition; |
| import jdk.test.lib.jittester.types.TypeArray; |
| import jdk.test.lib.jittester.types.TypeKlass; |
| |
| public class FixedTrees { |
| private static final Literal EOL = new Literal("\n", TypeList.STRING); |
| |
| public static FunctionDefinition printVariablesAsFunction(PrintVariables node) { |
| TypeKlass owner = node.getOwner(); |
| |
| ArrayList<IRNode> nodes = new ArrayList<>(); |
| |
| VariableInfo resultInfo = new VariableInfo("result", node.getOwner(), TypeList.STRING, VariableInfo.LOCAL); |
| nodes.add(new Statement(new VariableInitialization(resultInfo, new Literal("[", TypeList.STRING)), true)); |
| LocalVariable resultVar = new LocalVariable(resultInfo); |
| |
| List<Symbol> vars = node.getVars(); |
| |
| TypeKlass printerKlass = new TypeKlass(Printer.class.getName()); |
| VariableInfo thisInfo = new VariableInfo("this", node.getOwner(), |
| node.getOwner(), VariableInfo.LOCAL | VariableInfo.INITIALIZED); |
| |
| LocalVariable thisVar = new LocalVariable(thisInfo); |
| |
| for (int i = 0; i < vars.size(); i++) { |
| Symbol v = vars.get(i); |
| nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, |
| new Literal(v.owner.getName() + "." + v.name + " = ", TypeList.STRING)), true)); |
| VariableInfo argInfo = new VariableInfo("arg", printerKlass, |
| v.type instanceof TypeKlass ? TypeList.OBJECT : v.type, |
| VariableInfo.LOCAL | VariableInfo.INITIALIZED); |
| FunctionInfo printInfo = new FunctionInfo("print", printerKlass, |
| TypeList.STRING, 0, FunctionInfo.PUBLIC | FunctionInfo.STATIC, argInfo); |
| Function call = new Function(owner, printInfo, null); |
| VariableInfo varInfo = new VariableInfo(v.name, v.owner, v.type, v.flags); |
| if (v.isStatic()) { |
| call.addChild(new StaticMemberVariable(v.owner, varInfo)); |
| } else { |
| call.addChild(new NonStaticMemberVariable(thisVar, varInfo)); |
| } |
| nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, |
| call), true)); |
| if (i < vars.size() - 1) { |
| nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, |
| EOL), true)); |
| } |
| } |
| nodes.add(new Statement( |
| new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, new Literal("]\n", TypeList.STRING)), |
| true)); |
| |
| Block block = new Block(node.getOwner(), TypeList.STRING, nodes, 1); |
| FunctionInfo toStringInfo = new FunctionInfo("toString", owner, TypeList.STRING, 0L, FunctionInfo.PUBLIC, thisInfo); |
| return new FunctionDefinition(toStringInfo, new ArrayList<>(), block, new Return(resultVar)); |
| } |
| |
| public static FunctionDefinition generateMainOrExecuteMethod(TypeKlass owner, boolean isMain) { |
| Nothing nothing = new Nothing(); |
| ArrayList<IRNode> testCallNodeContent = new ArrayList<>(); |
| VariableInfo tInfo = new VariableInfo("t", owner, owner, VariableInfo.LOCAL); |
| LocalVariable tVar = new LocalVariable(tInfo); |
| Function testCallNode = new Function(owner, new FunctionInfo("test", owner, TypeList.VOID, |
| 0L, FunctionInfo.PRIVATE, tInfo), null); |
| testCallNode.addChild(tVar); |
| testCallNodeContent.add(new Statement(testCallNode, true)); |
| // { t.test(); } |
| Block testCallNodeBlock = new Block(owner, TypeList.VOID, testCallNodeContent, 4); |
| |
| IRNode tryNode = testCallNodeBlock; |
| if (isMain) { |
| VariableInfo iInfo = new VariableInfo("i", owner, TypeList.INT, VariableInfo.LOCAL); |
| LocalVariable iVar = new LocalVariable(iInfo); |
| Operator increaseCounter = new BinaryOperator(OperatorKind.ASSIGN, TypeList.INT, |
| iVar, |
| new BinaryOperator(OperatorKind.ADD, TypeList.INT, |
| iVar, new Literal(1, TypeList.INT))); |
| Loop loop = new Loop(); |
| Block emptyBlock = new Block(owner, TypeList.VOID, new LinkedList<>(), 3); |
| loop.initialization = new CounterInitializer(iInfo, new Literal(0, TypeList.INT)); |
| loop.manipulator = new CounterManipulator(new Statement(increaseCounter, false)); |
| loop.condition = new LoopingCondition(new BinaryOperator(OperatorKind.LT, TypeList.BOOLEAN, iVar, |
| new Literal(150000, TypeList.INT))); |
| For forNode = new For(4, loop, 150000, emptyBlock, new Statement(nothing, false), |
| new Statement(nothing, false), testCallNodeBlock, emptyBlock, emptyBlock); |
| tryNode = forNode; |
| } |
| |
| FunctionInfo constrInfo = new FunctionInfo(owner.getName(), owner, owner, 0, FunctionInfo.PUBLIC); |
| Function testConstructor = new Function(owner, constrInfo, null); |
| // Test t = new Test() |
| VariableInitialization testInit = new VariableInitialization(tInfo, testConstructor); |
| |
| TypeKlass throwableKlass = new TypeKlass("java.lang.Throwable"); |
| List<Type> throwables = new ArrayList<>(); |
| throwables.add(throwableKlass); |
| |
| TypeKlass printStreamKlass = new TypeKlass("java.io.PrintStream"); |
| FunctionInfo printInfo = new FunctionInfo("print", printStreamKlass, |
| TypeList.VOID, 0, FunctionInfo.PUBLIC, |
| new VariableInfo("this", owner, printStreamKlass, VariableInfo.LOCAL | VariableInfo.INITIALIZED), |
| new VariableInfo("t", owner, TypeList.OBJECT, |
| VariableInfo.LOCAL | VariableInfo.INITIALIZED)); |
| TypeKlass systemKlass = new TypeKlass("java.lang.System"); |
| StaticMemberVariable systemErrVar = new StaticMemberVariable(owner, |
| new VariableInfo("err", systemKlass, printStreamKlass, VariableInfo.STATIC | VariableInfo.PUBLIC)); |
| |
| LocalVariable exVar = new LocalVariable( |
| new VariableInfo("ex", owner, throwableKlass, VariableInfo.LOCAL | VariableInfo.INITIALIZED)); |
| TypeKlass classKlass = new TypeKlass("java.lang.Class"); |
| FunctionInfo getClassInfo = new FunctionInfo("getClass", TypeList.OBJECT, |
| classKlass, 0, FunctionInfo.PUBLIC, |
| new VariableInfo("this", owner, TypeList.OBJECT, VariableInfo.LOCAL | VariableInfo.INITIALIZED)); |
| Function getClass = new Function(TypeList.OBJECT, getClassInfo, Arrays.asList(exVar)); |
| FunctionInfo getNameInfo = new FunctionInfo("getName", classKlass, |
| TypeList.STRING, 0, FunctionInfo.PUBLIC, |
| new VariableInfo("this", owner, TypeList.OBJECT, VariableInfo.LOCAL | VariableInfo.INITIALIZED)); |
| Function getName = new Function(classKlass, getNameInfo, Arrays.asList(getClass)); |
| ArrayList<IRNode> printExceptionBlockContent = new ArrayList<>(); |
| // { System.err.print(ex.getClass().getName()); System.err.print("\n"); } |
| printExceptionBlockContent.add(new Statement( |
| new Function(printStreamKlass, printInfo, Arrays.asList(systemErrVar, getName)), true)); |
| printExceptionBlockContent.add(new Statement( |
| new Function(printStreamKlass, printInfo, Arrays.asList(systemErrVar, EOL)), true)); |
| |
| Block printExceptionBlock = new Block(owner, TypeList.VOID, printExceptionBlockContent, 3); |
| List<CatchBlock> catchBlocks1 = new ArrayList<>(); |
| catchBlocks1.add(new CatchBlock(printExceptionBlock, throwables, 3)); |
| List<CatchBlock> catchBlocks2 = new ArrayList<>(); |
| catchBlocks2.add(new CatchBlock(printExceptionBlock, throwables, 3)); |
| List<CatchBlock> catchBlocks3 = new ArrayList<>(); |
| catchBlocks3.add(new CatchBlock(printExceptionBlock, throwables, 2)); |
| |
| TryCatchBlock tryCatch1 = new TryCatchBlock(tryNode, nothing, catchBlocks1, 3); |
| List<IRNode> printArgs = new ArrayList<>(); |
| VariableInfo systemOutInfo = new VariableInfo("out", systemKlass, printStreamKlass, |
| VariableInfo.STATIC | VariableInfo.PUBLIC); |
| StaticMemberVariable systemOutVar = new StaticMemberVariable(owner, systemOutInfo); |
| printArgs.add(systemOutVar); |
| printArgs.add(tVar); |
| Function print = new Function(printStreamKlass, printInfo, printArgs); |
| ArrayList<IRNode> printBlockContent = new ArrayList<>(); |
| printBlockContent.add(new Statement(print, true)); |
| Block printBlock = new Block(owner, TypeList.VOID, printBlockContent, 3); |
| TryCatchBlock tryCatch2 = new TryCatchBlock(printBlock, nothing, catchBlocks2, 3); |
| |
| List<IRNode> mainTryCatchBlockContent = new ArrayList<>(); |
| mainTryCatchBlockContent.add(new Statement(testInit, true)); |
| mainTryCatchBlockContent.add(tryCatch1); |
| mainTryCatchBlockContent.add(tryCatch2); |
| Block mainTryCatchBlock = new Block(owner, TypeList.VOID, mainTryCatchBlockContent, 2); |
| TryCatchBlock mainTryCatch = new TryCatchBlock(mainTryCatchBlock, nothing, catchBlocks3, 2); |
| ArrayList<IRNode> bodyContent = new ArrayList<>(); |
| bodyContent.add(mainTryCatch); |
| Block funcBody = new Block(owner, TypeList.VOID, bodyContent, 1); |
| |
| // static main(String[] args)V or static execute()V |
| VariableInfo mainArgs = new VariableInfo("args", owner, |
| new TypeArray(TypeList.STRING, 1), VariableInfo.LOCAL); |
| FunctionInfo fInfo = isMain |
| ? new FunctionInfo("main", owner, TypeList.VOID, 0, FunctionInfo.PUBLIC | FunctionInfo.STATIC, mainArgs) |
| : new FunctionInfo("execute", owner, TypeList.VOID, 0, FunctionInfo.PUBLIC | FunctionInfo.STATIC); |
| ArrayList<ArgumentDeclaration> argDecl = new ArrayList<>(); |
| if (isMain) { |
| argDecl.add(new ArgumentDeclaration(mainArgs)); |
| } |
| return new FunctionDefinition(fInfo, argDecl, funcBody, new Return(nothing)); |
| } |
| } |