blob: 1f25d4a3d41d212cf75135033e3fb91c93b4cf3e [file] [log] [blame]
/*
* 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));
}
}